/// <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); }
/// <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); }
/// <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)); }
/// <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); }