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