/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { // Express the end of the horizontal in a local system with // the same origin as the circle this arc lies on. IPosition center = m_Circle.Center; QuadVertex pos = new QuadVertex(center, hr.End); Quadrant quad = pos.Quadrant; // Assign the side code, assuming the arc is clockwise. Side result = (quad == Quadrant.NE || quad == Quadrant.SE ? Side.Right : Side.Left); // If the horizontal is apparently to the right of the curve, // but the location in question coincides with the extreme // north point of the circle, reverse the side (it's OK in // the extreme south). if (result == Side.Right) { double maxnorth = center.Y + Circle.Radius; if (Math.Abs(maxnorth - hr.Y) < Constants.TINY) { result = Side.Left; } } // If the arc actually goes anti-clockwise, reverse the side. if (!m_IsClockwise) { result = (result == Side.Left ? Side.Right : Side.Left); } return(result); }
/// <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; // Remember the initial end of segment PointGeometry initEnd = new PointGeometry(e); // 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); } IPointGeometry[] data = this.Data; // Get relative position code for the start of the line. If it's // somewhere on the horizontal segment, cut the line back. byte scode = Geom.GetPositionCode(data[0], s, e); if (scode == 0) { e = new PointGeometry(Start); } // Loop through each line segment, testing the end of each segment // against the horizontal segment. byte ecode; for (int i = 1; i < data.Length; scode = ecode, i++) { // Get the position code for the end of the line segment ecode = Geom.GetPositionCode(data[i], s, e); // If it's coincident with the horizontal segment, cut the // line back. Otherwise see whether there is any potential // intersection to cut back to. if (ecode == 0) { e = new PointGeometry(data[i]); } else if ((scode & ecode) == 0) { IPosition x = null; if (hseg.Intersect(data[i - 1], data[i], ref x)) { e = new PointGeometry(x); } } } // Return flag to indicate whether we got closer or not. return(!e.IsCoincident(initEnd)); }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { // Find the segment containing the end of the horizontal segment IPointGeometry[] data = Data; int seg = FindSegment(data, true, 0, hr.End); if (seg < 0) { return(Side.Unknown); // not found => big problem! } // What's the northing of the horizontal segment guy? double hy = hr.Y; // Scan the remainder of the line, looking for a point which is // off the horizontal. If below the horizontal, it's to the right // of the line (& above=>left). for (int i = seg + 1; i < data.Length; i++) { double y = data[i].Y; if ((hy - y) > Constants.TINY) // y<hy { return(Side.Right); } if ((y - hy) > Constants.TINY) // y>hy { return(Side.Left); } } // If we didn't find any suitable points, try traversing back down // the line, and adopt the reverse logic for figuring out the side. for (int i = seg; i >= 0; i--) { double y = data[i].Y; if ((y - hy) > Constants.TINY) // y>hy { return(Side.Right); } if ((hy - y) > Constants.TINY) // y<hy { return(Side.Left); } } // The line is completely horizontal, so we have an intersection // at the start or the end of the line. This should have already // been caught, so we're f****d now. return(Side.Unknown); }
/// <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; // Remember the initial end of segment PointGeometry initEnd = new PointGeometry(e); // 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); } // Get relative position code for the start of the line. If it's // somewhere on the horizontal segment, cut the line back. byte scode = Geom.GetPositionCode(Start, s, e); if (scode == 0) { e = new PointGeometry(Start); } // Get the position code for the end of the line segment byte ecode = Geom.GetPositionCode(End, s, e); // If it's coincident with the horizontal segment, cut the // line back. Otherwise see whether there is any potential // intersection to cut back to. if (ecode == 0) { e = new PointGeometry(End); } else if ((scode & ecode) == 0) { IPosition x = null; if (hseg.Intersect(Start, End, ref x)) { e = new PointGeometry(x); } } // Return flag to indicate whether we got closer or not. return(!e.IsCoincident(initEnd)); }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { // The end of the horizontal segment should be coincident with this segment. IPosition e = hr.End; if (this.Distance(e).Meters > Constants.XYTOL) { return(Side.Unknown); } // What's the northing of the horizontal segment guy? double hy = hr.Y; // Scan the remainder of the line, looking for a point which is // off the horizontal. If below the horizontal, it's to the right // of the line (& above=>left). double y = End.Y; if ((hy - y) > Constants.TINY) // y<hy { return(Side.Right); } if ((y - hy) > Constants.TINY) // y>hy { return(Side.Left); } // If we didn't find any suitable points, try traversing back down // the line, and adopt the reverse logic for figuring out the side. y = Start.Y; if ((y - hy) > Constants.TINY) // y>hy { return(Side.Right); } if ((hy - y) > Constants.TINY) // y<hy { return(Side.Left); } // The line is completely horizontal, so we have an intersection // at the start or the end of the line. This should have already // been caught, so we're f****d now. return(Side.Unknown); }
/// <summary> /// Creates new <c>Orientation</c> based on the supplied horizontal ray. /// </summary> /// <param name="hr"></param> internal Orientation(HorizontalRay hr) { // Remember the stuff we were supplied (since we are not starting // with a divider, it has to be null). m_Divider = null; m_IsStart = false; // The horizontal segment is ALWAYS at the very start of the // north-west quadrant. m_Quadrant = Quadrant.NW; // Convert the deltas into the IJ coordinate system for the // north-west quadrant (the angle defined with I/J should // evaluate to zero, since the horizontal segment is at the // start of the quadrant). m_DeltaI = 0.0; m_DeltaJ = hr.EndX - hr.StartX; }
/// <summary> /// Determines which side of a divider a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="id">The divider to process</param> /// <param name="s">Start of horizontal segment.</param> /// <param name="e">End of segment.</param> /// <param name="od">The divider the side refers to. This usually refers to /// the supplied divider, but may refer to another divider in a situation where the /// horizontal segment passes directly through one end of <paramref name="d"/>.</param> /// <returns>Side.Left if the line is to the left of the divider, Side.Right /// if line to the right, Side.On if the end of the line is coincident with /// the divider, Side.Unknown if an error arose.</returns> /// <remarks> /// Rather than passing in 2 PointGeometry objects, it would be better to pass /// in a HorizontalRay object, since 2 arbitrary positions are not guaranteed /// to be horizontal. /// </remarks> internal static Side GetSide(IDivider id, IPointGeometry s, IPointGeometry e, out IDivider od) { // If the end of the horizontal segment hits the start or // the end of the specified divider, we have a situation where the divider // may not be the divider which is adjacent to the segment. In // that case, use special code to determine the side code. // Otherwise just convert the supplied divider into a line, and get the // side code by looking for a vertex which has a different // northing from that of the horizontal segment. Debug.Assert(s.Easting.Microns <= e.Easting.Microns); double d = e.Easting.Meters - s.Easting.Meters; Debug.Assert(d>=0.0); HorizontalRay hseg = new HorizontalRay(s, d); if (e.IsCoincident(id.From) || e.IsCoincident(id.To)) // e both times! return hseg.GetSide(id, e.IsCoincident(id.From), out od); else { od = id; return od.LineGeometry.GetSide(hseg); } }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { // The end of the horizontal segment should be coincident with this segment. IPosition e = hr.End; if (this.Distance(e).Meters > Constants.XYTOL) return Side.Unknown; // What's the northing of the horizontal segment guy? double hy = hr.Y; // Scan the remainder of the line, looking for a point which is // off the horizontal. If below the horizontal, it's to the right // of the line (& above=>left). double y = End.Y; if ((hy-y) > Constants.TINY) // y<hy return Side.Right; if ((y-hy) > Constants.TINY) // y>hy return Side.Left; // If we didn't find any suitable points, try traversing back down // the line, and adopt the reverse logic for figuring out the side. y = Start.Y; if ((y-hy) > Constants.TINY) // y>hy return Side.Right; if ((hy-y) > Constants.TINY) // y<hy return Side.Left; // The line is completely horizontal, so we have an intersection // at the start or the end of the line. This should have already // been caught, so we're f****d now. return Side.Unknown; }
/// <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; // Remember the initial end of segment PointGeometry initEnd = new PointGeometry(e); // 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; } // Get relative position code for the start of the line. If it's // somewhere on the horizontal segment, cut the line back. byte scode = Geom.GetPositionCode(Start, s, e); if (scode==0) e = new PointGeometry(Start); // Get the position code for the end of the line segment byte ecode = Geom.GetPositionCode(End, s, e); // If it's coincident with the horizontal segment, cut the // line back. Otherwise see whether there is any potential // intersection to cut back to. if (ecode==0) e = new PointGeometry(End); else if ((scode & ecode)==0) { IPosition x = null; if (hseg.Intersect(Start, End, ref x)) e = new PointGeometry(x); } // Return flag to indicate whether we got closer or not. return (!e.IsCoincident(initEnd)); }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { // Express the end of the horizontal in a local system with // the same origin as the circle this arc lies on. IPosition center = m_Circle.Center; QuadVertex pos = new QuadVertex(center, hr.End); Quadrant quad = pos.Quadrant; // Assign the side code, assuming the arc is clockwise. Side result = (quad==Quadrant.NE || quad==Quadrant.SE ? Side.Right : Side.Left); // If the horizontal is apparently to the right of the curve, // but the location in question coincides with the extreme // north point of the circle, reverse the side (it's OK in // the extreme south). if (result==Side.Right) { double maxnorth = center.Y + Circle.Radius; if (Math.Abs(maxnorth - hr.Y) < Constants.TINY) result = Side.Left; } // If the arc actually goes anti-clockwise, reverse the side. if (!m_IsClockwise) result = (result==Side.Left ? Side.Right : Side.Left); return result; }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { return Make().GetSide(hr); }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { return(Make().GetSide(hr)); }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal abstract Side GetSide(HorizontalRay hr);
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> internal override Side GetSide(HorizontalRay hr) { // Find the segment containing the end of the horizontal segment IPointGeometry[] data = Data; int seg = FindSegment(data, true, 0, hr.End); if (seg<0) return Side.Unknown; // not found => big problem! // What's the northing of the horizontal segment guy? double hy = hr.Y; // Scan the remainder of the line, looking for a point which is // off the horizontal. If below the horizontal, it's to the right // of the line (& above=>left). for (int i=seg+1; i<data.Length; i++) { double y = data[i].Y; if ((hy-y) > Constants.TINY) // y<hy return Side.Right; if ((y-hy) > Constants.TINY) // y>hy return Side.Left; } // If we didn't find any suitable points, try traversing back down // the line, and adopt the reverse logic for figuring out the side. for (int i=seg; i>=0; i--) { double y = data[i].Y; if ((y-hy) > Constants.TINY) // y>hy return Side.Right; if ((hy-y) > Constants.TINY) // y<hy return Side.Left; } // The line is completely horizontal, so we have an intersection // at the start or the end of the line. This should have already // been caught, so we're f****d now. return Side.Unknown; }
/// <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; // Remember the initial end of segment PointGeometry initEnd = new PointGeometry(e); // 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; } IPointGeometry[] data = this.Data; // Get relative position code for the start of the line. If it's // somewhere on the horizontal segment, cut the line back. byte scode = Geom.GetPositionCode(data[0], s, e); if (scode==0) e = new PointGeometry(Start); // Loop through each line segment, testing the end of each segment // against the horizontal segment. byte ecode; for (int i=1; i<data.Length; scode=ecode, i++) { // Get the position code for the end of the line segment ecode = Geom.GetPositionCode(data[i], s, e); // If it's coincident with the horizontal segment, cut the // line back. Otherwise see whether there is any potential // intersection to cut back to. if (ecode==0) e = new PointGeometry(data[i]); else if ((scode & ecode)==0) { IPosition x=null; if (hseg.Intersect(data[i-1], data[i], ref x)) e = new PointGeometry(x); } } // Return flag to indicate whether we got closer or not. return (!e.IsCoincident(initEnd)); }
/// <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); }
/// <summary> /// Determines which side of a line a horizontal line segment lies on. /// Used in point in polygon. /// </summary> /// <param name="hr">The horizontal line segment</param> /// <returns>Code indicating the position of the horizontal segment with respect to this line. /// Side.Left if the horizontal segment is to the left of this line; Side.Right if to the /// right of this line; Side.Unknown if the side cannot be determined (this line is /// horizontal). /// </returns> abstract internal Side GetSide(HorizontalRay hr);
/// <summary> /// Creates a new <c>ConnectionFinder</c> at a specific end of a divider. /// Defines the next divider in the nodal cycle (reckoned anticlockwise), /// along with a flag to indicate whether it is the start or end of the divider. /// <para/> /// If the parameters supplied refer to a dangling divider, the result will /// be the SAME as the supplied info. /// <para/> /// This constructor is normally used during polygon formation. It is also used /// to resolve a special case in point in polygon tests, where the directed /// line (a <c>HorizontalRay</c> object) intersects at a node. In that case, /// the supplied divider refers to any one of the dividers incident on the /// node, and the connection to be formed is actually the connection for /// the <c>HorizontalRay</c> object. /// </summary> /// <param name="from">The divider entering the node.</param> /// <param name="isFromStart">True if it's the start of the divider.</param> /// <param name="ray">Optional reference line (used when doing special point /// in polygon tests).</param> internal ConnectionFinder(IDivider from, bool isFromStart, HorizontalRay ray) { Debug.Assert(from != null); // Initialize with default values m_Next = null; m_IsStart = false; // Get the location involved ITerminal loc = (isFromStart ? from.From : from.To); // Get the dividers incident on the terminal. IDivider[] da = loc.IncidentDividers(); // Get orientation info for each divider (the list could conceivably // grow if dividers start at the terminal, then loop round to also // finish at the same terminal). List <Orientation> orient = new List <Orientation>(da.Length); // If we are doing special stuff for point in polygon, add an extra orientation // object to refer to the HorizontalRay object. if (ray != null) { Orientation o = new Orientation(ray); orient.Add(o); } foreach (IDivider d in da) { // 03-APR-2003: Try ignoring boundaries that have zero-length //if (!b.HasLength) // continue; // Check if the start of the divider is incident on the node. // If so, append the orientation info to the list. if (d.From.IsCoincident(loc)) { orient.Add(new Orientation(d, true)); } // Likewise for the end of the divider (it could start AND end at the node). if (d.To.IsCoincident(loc)) { orient.Add(new Orientation(d, false)); } } // We MUST have at least one orientation point (two if a horizontal ray is also included) Debug.Assert(orient.Count > (ray == null ? 0 : 1)); // If we have only one orientation point, we have a dangle, // so return the information we were supplied. if (ray == null && orient.Count == 1) { m_Next = from; m_IsStart = isFromStart; return; } // Get a reference to the orientation info for the source divider (if // we are doing point in polygon stuff, we stashed the reference // segment in the first slot). Orientation source = null; if (ray != null) { source = orient[0]; } else { source = orient.Find(o => (o.Divider == from && o.IsStart == isFromStart)); Debug.Assert(source != null); } // If we have only two orientation points, the one we want // if the one which does not match the source. if (orient.Count == 2) { Orientation o = (source == orient[0] ? orient[1] : orient[0]); m_Next = o.Divider; m_IsStart = o.IsStart; return; } // Handle any curves. if (HasAnyCurves(orient)) { source.SetCurves(orient); } // If there are any other boundaries in the source quadrant, // try to find an anticlockwise divider (with the highest // orientation angle which is less than that of the source). Orientation next = FindPrevMax(source, orient); // If we got something, we're all done. if (next != null) { m_Next = next.Divider; m_IsStart = next.IsStart; return; } // Loop through the quadrants, looking for the next divider. We // scan the quadrants anticlockwise, including the source // quadrant we may have just processing (possibility that the // next divider is further on in the source quadrant). Quadrant search = NextQuadrant(source.Quadrant); for (int i = 0; i < 4; i++, search = NextQuadrant(search)) { next = FindMax(search, source, orient); if (next != null) { m_Next = next.Divider; m_IsStart = next.IsStart; return; } } throw new Exception("ConnectionFinder: network error"); }
/// <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; }