예제 #1
0
        /// <summary>
        /// Intersects this direction with a line.
        /// </summary>
        /// <param name="line">The line to intersect with.</param>
        /// <param name="closeTo">The point that the intersection should be closest to.
        /// Specify null if you don't care. In that case, if there are multiple intersections,
        /// you get the intersection that is closest to one of 3 points: the start of the
        /// direction line, the start of the line, or the end of the line.</param>
        /// <param name="xsect">The position of the intersection (if any). Null if not found.</param>
        /// <param name="closest">The default point that is closest to the intersection. Null if
        /// intersection wasn't found.</param>
        /// <returns>True if intersection was found.</returns>
        internal bool Intersect(LineFeature line
                                , PointFeature closeTo
                                , out IPosition xsect
                                , out PointFeature closest)
        {
            // Initialize results
            xsect   = null;
            closest = null;

            // Define the length of the direction line as the length
            // of a diagonal that crosses the map's extent.
            IWindow mapWin = SpatialController.Current.MapModel.Extent;

            Debug.Assert(mapWin != null);

            // If the window is currently undefined (e.g. during deserialization),
            // just use a really big distance.
            // TODO: This is a hack, but hopefully it may be shortlived, because
            // new logic is in the works for handling updates.
            double dist = (mapWin.IsEmpty ? 100000.0 : Geom.Distance(mapWin.Min, mapWin.Max));

            // Define the position of the direction line. DON'T use the from-
            // point, because there may be an offset to the direction.
            IPosition fromPos = this.StartPosition;
            IPosition toPos   = Geom.Polar(fromPos, this.Bearing.Radians, dist);

            // Construct a corresponding line segment.
            ITerminal       start = new FloatingTerminal(fromPos);
            ITerminal       end   = new FloatingTerminal(toPos);
            SegmentGeometry seg   = new SegmentGeometry(start, end);

            // Intersect the line segment with the other one.
            IntersectionResult xres = new IntersectionResult(line);
            uint nx = seg.Intersect(xres);

            if (nx == 0)
            {
                return(false);
            }

            // Determine which terminal point is the best. Start with the
            // ends of the intersected line.
            double mindsq = Double.MaxValue;

            if (xres.GetCloserPoint(line.StartPoint, ref mindsq, ref xsect))
            {
                closest = line.StartPoint;
            }

            if (xres.GetCloserPoint(line.EndPoint, ref mindsq, ref xsect))
            {
                closest = line.EndPoint;
            }

            // Check whether the direction from-point is any closer (the position may be
            // different from the start of the direction line, because the direction may
            // have an offset).

            if (xres.GetCloserPoint(this.From, ref mindsq, ref xsect))
            {
                closest = this.From;
            }

            // If a close-to point has been specified, that overrides
            // everything else (however, doing the above has the desired
            // effect of defining the best of the default points). In
            // this case, we allow an intersection that coincides with
            // the line being intersected.
            // -- actually, we don't, since GetClosest uses a > 0 test

            if (closeTo != null)
            {
                xres.GetClosest(closeTo, out xsect, 0.0);

                /*
                 * IPosition xCloseTo;
                 * xres.GetClosest(closeTo, out xCloseTo, 0.0);
                 *
                 * if (xCloseTo != null)
                 *  xsect = xCloseTo;
                 */
            }

            return(xsect != null);
        }
예제 #2
0
        /// <summary>
        /// Returns the intersection of the parallel with a line. A prior call to Calculate is required.
        /// </summary>
        /// <param name="line">The line to intersect with.</param>
        /// <param name="isEndParallel">Is the intersection biased towards the end of the parallel?</param>
        /// <returns>The intersection (if any). In cases where the line intersects the parallel
        /// more than once, you get an arbitrary intersection.</returns>
        internal IPosition GetIntersect(LineFeature line, bool isEndParallel)
        {
            // Make sure the intersection is undefined.
            IPosition result = null;

            // Return if the parallel points are undefined.
            if (m_Par1 == null || m_Par2 == null)
            {
                return(null);
            }

            // If the reference line is a circular arc, get the curve info.
            ArcFeature arc = m_Line.GetArcBase();

            if (arc != null)
            {
                Circle         circle = arc.Circle;
                double         radius = circle.Radius;
                IPointGeometry centre = circle.Center;
                bool           iscw   = arc.IsClockwise;

                // Construct a circle that passes through
                // the parallel points (assumed to have the same distance
                // with respect to the centre of the circle).
                double parrad = Geom.Distance(centre, m_Par1);

                // Intersect the circle with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                uint nx = xres.Intersect(centre, parrad);
                if (nx == 0)
                {
                    return(null);
                }

                // If there is only one intersection, that's what we want.
                if (nx == 1)
                {
                    return(xres.Intersections[0].P1);
                }

                // Get the intersection that is closest to the parallel point
                // that has the bias.
                if (isEndParallel)
                {
                    xres.GetClosest(m_Par2, out result, 0.0);
                }
                else
                {
                    xres.GetClosest(m_Par1, out result, 0.0);
                }
            }
            else
            {
                // Get the bearing from the start to the end of the parallel.
                double bearing = Geom.BearingInRadians(m_Par1, m_Par2);

                // Get the ground dimension of a line that crosses the
                // extent of the draw window.
                double dist = MaxDiagonal;

                // Project the parallel line to positions that are well
                // beyond the draw extent.
                IPosition start = Geom.Polar(m_Par1, bearing + Constants.PI, dist);
                IPosition end   = Geom.Polar(m_Par2, bearing, dist);

                // Intersect the line segment with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                IPointGeometry     sg   = PointGeometry.Create(start);
                IPointGeometry     eg   = PointGeometry.Create(end);
                uint nx = xres.Intersect(sg, eg);
                if (nx == 0)
                {
                    return(null);
                }

                // If there is only one intersection, that's what we want.
                if (nx == 1)
                {
                    return(xres.Intersections[0].P1);
                }

                // Get the intersection that is closest to the parallel point
                // that has the bias.
                if (isEndParallel)
                {
                    xres.GetClosest(m_Par2, out result, 0.0);
                }
                else
                {
                    xres.GetClosest(m_Par1, out result, 0.0);
                }
            }

            return(result);
        }
예제 #3
0
        /// <summary>
        /// Returns the intersection of the parallel with a line.
        /// </summary>
        /// <param name="refline">The reference line.</param>
        /// <param name="parpos">Search position that coincides with the parallel.</param>
        /// <param name="line">The line to intersect with.</param>
        /// <returns>The intersection (if any). In cases where the line intersects the
        /// parallel more than once, you get the intersection that is closest to the
        /// search position.</returns>
        internal static IPosition GetIntersect(LineFeature refline, IPosition parpos, LineFeature line)
        {
            // Make sure the intersection is undefined.
            IPosition result = null;

            // Return if the parallel point is undefined.
            if (parpos == null)
            {
                return(null);
            }

            // If the reference line is a circular arc (or a section based on an arc), get the curve info.
            ArcFeature arc = refline.GetArcBase();

            if (arc != null)
            {
                Circle         circle = arc.Circle;
                double         radius = circle.Radius;
                IPointGeometry centre = circle.Center;
                bool           iscw   = arc.IsClockwise;

                // Construct a circle that passes through the search position
                double parrad = Geom.Distance(centre, parpos);

                // Intersect the circle with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                uint nx = xres.Intersect(centre, parrad);
                if (nx == 0)
                {
                    return(null);
                }

                // If there is only one intersection, that's what we want.
                if (nx == 1)
                {
                    return(xres.Intersections[0].P1);
                }

                // Get the intersection that is closest to the search position.
                xres.GetClosest(parpos, out result, 0.0);
            }
            else
            {
                // Get the bearing from the start to the end of the reference line.
                IPosition spos    = refline.StartPoint;
                IPosition epos    = refline.EndPoint;
                double    bearing = Geom.BearingInRadians(spos, epos);

                // Project the parallel line to positions that are a long way away (but make sure we
                // don't end up with negative numbers).
                Window searchWindow = new Window(line.Extent);
                searchWindow.Union(refline.Extent);
                searchWindow.Union(parpos);
                double dist = Geom.Distance(searchWindow.Min, searchWindow.Max);

                IPosition start = Geom.Polar(parpos, bearing + Constants.PI, dist);
                IPosition end   = Geom.Polar(parpos, bearing, dist);

                // Intersect the line segment with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                IPointGeometry     sg   = new PointGeometry(start);
                IPointGeometry     eg   = new PointGeometry(end);
                uint nx = xres.Intersect(sg, eg);
                if (nx == 0)
                {
                    return(null);
                }

                // If there is only one intersection, that's what we want.
                if (nx == 1)
                {
                    return(xres.Intersections[0].P1);
                }

                // Get the intersection that is closest to the search position
                xres.GetClosest(parpos, out result, 0.0);
            }

            return(result);
        }
예제 #4
0
        /// <summary>
        /// Intersects this direction with a line.
        /// </summary>
        /// <param name="line">The line to intersect with.</param>
        /// <param name="closeTo">The point that the intersection should be closest to.
        /// Specify null if you don't care. In that case, if there are multiple intersections,
        /// you get the intersection that is closest to one of 3 points: the start of the
        /// direction line, the start of the line, or the end of the line.</param>
        /// <param name="xsect">The position of the intersection (if any). Null if not found.</param>
        /// <param name="closest">The default point that is closest to the intersection. Null if
        /// intersection wasn't found.</param>
        /// <returns>True if intersection was found.</returns>
        internal bool Intersect( LineFeature line
            , PointFeature closeTo
            , out IPosition xsect
            , out PointFeature closest)
        {
            // Initialize results
            xsect = null;
            closest = null;

            // Define the length of the direction line as the length
            // of a diagonal that crosses the map's extent.
            IWindow mapWin = SpatialController.Current.MapModel.Extent;
            Debug.Assert(mapWin!=null);

            // If the window is currently undefined (e.g. during deserialization),
            // just use a really big distance.
            // TODO: This is a hack, but hopefully it may be shortlived, because
            // new logic is in the works for handling updates.
            double dist = (mapWin.IsEmpty ? 100000.0 : Geom.Distance(mapWin.Min, mapWin.Max));

            // Define the position of the direction line. DON'T use the from-
            // point, because there may be an offset to the direction.
            IPosition fromPos = this.StartPosition;
            IPosition toPos = Geom.Polar(fromPos, this.Bearing.Radians, dist);

            // Construct a corresponding line segment.
            ITerminal start = new FloatingTerminal(fromPos);
            ITerminal end = new FloatingTerminal(toPos);
            SegmentGeometry seg = new SegmentGeometry(start, end);

            // Intersect the line segment with the other one.
            IntersectionResult xres = new IntersectionResult(line);
            uint nx = seg.Intersect(xres);
            if (nx==0)
                return false;

            // Determine which terminal point is the best. Start with the
            // ends of the intersected line.
            double mindsq = Double.MaxValue;

            if (xres.GetCloserPoint(line.StartPoint, ref mindsq, ref xsect))
                closest = line.StartPoint;

            if (xres.GetCloserPoint(line.EndPoint, ref mindsq, ref xsect))
                closest = line.EndPoint;

            // Check whether the direction from-point is any closer (the position may be
            // different from the start of the direction line, because the direction may
            // have an offset).

            if (xres.GetCloserPoint(this.From, ref mindsq, ref xsect))
                closest = this.From;

            // If a close-to point has been specified, that overrides
            // everything else (however, doing the above has the desired
            // effect of defining the best of the default points). In
            // this case, we allow an intersection that coincides with
            // the line being intersected.
            // -- actually, we don't, since GetClosest uses a > 0 test

            if (closeTo != null)
            {
                xres.GetClosest(closeTo, out xsect, 0.0);
                /*
                IPosition xCloseTo;
                xres.GetClosest(closeTo, out xCloseTo, 0.0);

                if (xCloseTo != null)
                    xsect = xCloseTo;
                 */
            }

            return (xsect!=null);
        }
예제 #5
0
        /// <summary>
        /// Returns the intersection of the parallel with a line. A prior call to Calculate is required.
        /// </summary>
        /// <param name="line">The line to intersect with.</param>
        /// <param name="isEndParallel">Is the intersection biased towards the end of the parallel?</param>
        /// <returns>The intersection (if any). In cases where the line intersects the parallel
        /// more than once, you get an arbitrary intersection.</returns>
        internal IPosition GetIntersect(LineFeature line, bool isEndParallel)
        {
            // Make sure the intersection is undefined.
            IPosition result = null;

            // Return if the parallel points are undefined.
            if (m_Par1==null || m_Par2==null)
                return null;

            // If the reference line is a circular arc, get the curve info.
            ArcFeature arc = m_Line.GetArcBase();
            if (arc != null)
            {
                Circle circle = arc.Circle;
                double radius = circle.Radius;
                IPointGeometry centre = circle.Center;
                bool iscw = arc.IsClockwise;

                // Construct a circle that passes through
                // the parallel points (assumed to have the same distance
                // with respect to the centre of the circle).
                double parrad = Geom.Distance(centre, m_Par1);

                // Intersect the circle with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                uint nx = xres.Intersect(centre, parrad);
                if (nx==0)
                    return null;

                // If there is only one intersection, that's what we want.
                if (nx==1)
                    return xres.Intersections[0].P1;

                // Get the intersection that is closest to the parallel point
                // that has the bias.
                if (isEndParallel)
                    xres.GetClosest(m_Par2, out result, 0.0);
                else
                    xres.GetClosest(m_Par1, out result, 0.0);
            }
            else
            {
                // Get the bearing from the start to the end of the parallel.
                double bearing = Geom.BearingInRadians(m_Par1, m_Par2);

                // Get the ground dimension of a line that crosses the
                // extent of the draw window.
                double dist = MaxDiagonal;

                // Project the parallel line to positions that are well
                // beyond the draw extent.
                IPosition start = Geom.Polar(m_Par1, bearing+Constants.PI, dist);
                IPosition end = Geom.Polar(m_Par2, bearing, dist);

                // Intersect the line segment with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                IPointGeometry sg = PointGeometry.Create(start);
                IPointGeometry eg = PointGeometry.Create(end);
                uint nx = xres.Intersect(sg, eg);
                if (nx==0)
                    return null;

                // If there is only one intersection, that's what we want.
                if (nx==1)
                    return xres.Intersections[0].P1;

                // Get the intersection that is closest to the parallel point
                // that has the bias.
                if (isEndParallel)
                    xres.GetClosest(m_Par2, out result, 0.0);
                else
                    xres.GetClosest(m_Par1, out result, 0.0);
            }

            return result;
        }
예제 #6
0
        /// <summary>
        /// Returns the intersection of the parallel with a line.
        /// </summary>
        /// <param name="refline">The reference line.</param>
        /// <param name="parpos">Search position that coincides with the parallel.</param>
        /// <param name="line">The line to intersect with.</param>
        /// <returns>The intersection (if any). In cases where the line intersects the
        /// parallel more than once, you get the intersection that is closest to the
        /// search position.</returns>
        internal static IPosition GetIntersect(LineFeature refline, IPosition parpos, LineFeature line)
        {
            // Make sure the intersection is undefined.
            IPosition result = null;

            // Return if the parallel point is undefined.
            if (parpos==null)
                return null;

            // If the reference line is a circular arc (or a section based on an arc), get the curve info.
            ArcFeature arc = refline.GetArcBase();
            if (arc != null)
            {
                Circle circle = arc.Circle;
                double radius = circle.Radius;
                IPointGeometry centre = circle.Center;
                bool iscw = arc.IsClockwise;

                // Construct a circle that passes through the search position
                double parrad = Geom.Distance(centre, parpos);

                // Intersect the circle with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                uint nx = xres.Intersect(centre, parrad);
                if (nx==0)
                    return null;

                // If there is only one intersection, that's what we want.
                if (nx==1)
                    return xres.Intersections[0].P1;

                // Get the intersection that is closest to the search position.
                xres.GetClosest(parpos, out result, 0.0);
            }
            else
            {
                // Get the bearing from the start to the end of the reference line.
                IPosition spos = refline.StartPoint;
                IPosition epos = refline.EndPoint;
                double bearing = Geom.BearingInRadians(spos, epos);

                // Project the parallel line to positions that are a long way away (but make sure we
                // don't end up with negative numbers).
                Window searchWindow = new Window(line.Extent);
                searchWindow.Union(refline.Extent);
                searchWindow.Union(parpos);
                double dist = Geom.Distance(searchWindow.Min, searchWindow.Max);

                IPosition start = Geom.Polar(parpos, bearing+Constants.PI, dist);
                IPosition end = Geom.Polar(parpos, bearing, dist);

                // Intersect the line segment with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                IPointGeometry sg = new PointGeometry(start);
                IPointGeometry eg = new PointGeometry(end);
                uint nx = xres.Intersect(sg, eg);
                if (nx==0)
                    return null;

                // If there is only one intersection, that's what we want.
                if (nx==1)
                    return xres.Intersections[0].P1;

                // Get the intersection that is closest to the search position
                xres.GetClosest(parpos, out result, 0.0);
            }

            return result;
        }