Beispiel #1
0
        /// <summary>
        /// Geometry that can be used to detect intersections with the map
        /// </summary>
        /// <returns>The geometry for the new line (null if insufficient information has been specified)</returns>
        internal virtual LineGeometry GetIntersectGeometry()
        {
            if (m_Start == null || m_End == null)
            {
                return(null);
            }

            ITerminal endTerm = new FloatingTerminal(m_End);

            return(new SegmentGeometry(m_Start, endTerm));
        }
        /// <summary>
        /// Creates the geometry that can be used to detect intersections with the map.
        /// </summary>
        /// <returns>The geometry for the new line (null if insufficient information has been specified)</returns>
        ArcGeometry CreateIntersectGeometry()
        {
            if (m_Circles==null)
                return null;

            PointFeature start = StartPoint;
            if (start==null)
                return null;

            IPointGeometry end = LastMousePosition;
            if (end==null)
                return null;

            ITerminal endTerm = new FloatingTerminal(end);

            // Find the circle that is closest to the end (only looking at the valid circles
            // that are within a 1mm tolerance). Return null geometry if none of the circles
            // are within reach.

            Circle bestCircle = m_Circles[0];
            double bestdist = bestCircle.Distance(end).Meters;

            if (m_Circles.Count > 1)
            {
                // See if there is any better choice
                for (int i=1; i<m_Circles.Count; i++)
                {
                    Circle c = m_Circles[i];
                    double dist = c.Distance(end).Meters;
                    if (dist < bestdist)
                    {
                        bestCircle = c;
                        bestdist = dist;
                    }
                }
            }

            // Ignore if the best circle is too far away
            double tol = CircleTolerance.Meters;
            if (bestdist > tol)
                return null;

            // Project the end point ON to the circle.
            //IPointGeometry center = bestCircle.Center;
            //Turn eturn = new Turn(center, end);
            //IAngle bearing = eturn.Bearing;
            //IPosition cirend = Geom.Polar(center, bearing.Radians, bestCircle.Radius.Meters);
            IPosition cirend = CircleGeometry.GetClosestPosition(bestCircle, end);

            // Get the clockwise angle from the start to the current end point.
            IPointGeometry center = bestCircle.Center;
            Turn sturn = new Turn(center, start);
            double angle = sturn.GetAngleInRadians(cirend);

            // Figure out which direction the curve should go, depending
            // on whether the user wants the short arc or the long one.
            bool iscw = (angle < MathConstants.PI ? m_IsShortArc : !m_IsShortArc);

            // Create the required geometry
            ITerminal ec = new FloatingTerminal(cirend);
            return new ArcGeometry(bestCircle, start, ec, iscw);
        }
Beispiel #3
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);
        }
Beispiel #4
0
        /// <summary>
        /// Geometry that can be used to detect intersections with the map
        /// </summary>
        /// <returns>The geometry for the new line (null if insufficient information has been specified)</returns>
        internal virtual LineGeometry GetIntersectGeometry()
        {
            if (m_Start==null || m_End==null)
                return null;

            ITerminal endTerm = new FloatingTerminal(m_End);
            return new SegmentGeometry(m_Start, endTerm);
        }
Beispiel #5
0
        /// <summary>
        /// Creates the geometry that can be used to detect intersections with the map.
        /// </summary>
        /// <returns>The geometry for the new line (null if insufficient information has been specified)</returns>
        ArcGeometry CreateIntersectGeometry()
        {
            if (m_Circles == null)
            {
                return(null);
            }

            PointFeature start = StartPoint;

            if (start == null)
            {
                return(null);
            }

            IPointGeometry end = LastMousePosition;

            if (end == null)
            {
                return(null);
            }

            ITerminal endTerm = new FloatingTerminal(end);

            // Find the circle that is closest to the end (only looking at the valid circles
            // that are within a 1mm tolerance). Return null geometry if none of the circles
            // are within reach.

            Circle bestCircle = m_Circles[0];
            double bestdist   = bestCircle.Distance(end).Meters;

            if (m_Circles.Count > 1)
            {
                // See if there is any better choice
                for (int i = 1; i < m_Circles.Count; i++)
                {
                    Circle c    = m_Circles[i];
                    double dist = c.Distance(end).Meters;
                    if (dist < bestdist)
                    {
                        bestCircle = c;
                        bestdist   = dist;
                    }
                }
            }

            // Ignore if the best circle is too far away
            double tol = CircleTolerance.Meters;

            if (bestdist > tol)
            {
                return(null);
            }

            // Project the end point ON to the circle.
            //IPointGeometry center = bestCircle.Center;
            //Turn eturn = new Turn(center, end);
            //IAngle bearing = eturn.Bearing;
            //IPosition cirend = Geom.Polar(center, bearing.Radians, bestCircle.Radius.Meters);
            IPosition cirend = CircleGeometry.GetClosestPosition(bestCircle, end);

            // Get the clockwise angle from the start to the current end point.
            IPointGeometry center = bestCircle.Center;
            Turn           sturn  = new Turn(center, start);
            double         angle  = sturn.GetAngleInRadians(cirend);

            // Figure out which direction the curve should go, depending
            // on whether the user wants the short arc or the long one.
            bool iscw = (angle < MathConstants.PI ? m_IsShortArc : !m_IsShortArc);

            // Create the required geometry
            ITerminal ec = new FloatingTerminal(cirend);

            return(new ArcGeometry(bestCircle, start, ec, iscw));
        }
Beispiel #6
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);
        }