/// <summary> /// Insert nodes for all intersections on the edges of a Geometry. /// Label the created nodes the same as the edge label if they do not already /// have a label. /// This allows nodes created by either self-intersections or /// mutual intersections to be labelled. /// Endpoint nodes will already be labelled from when they were inserted. /// <para> /// Precondition: edge intersections have been computed. /// </para> /// </summary> public void ComputeIntersectionNodes(GeometryGraph geomGraph, int argIndex) { for (IEdgeEnumerator edgeIt = geomGraph.EdgeIterator; edgeIt.MoveNext();) { Edge e = edgeIt.Current; int eLoc = e.Label.GetLocation(argIndex); for (IEnumerator eiIt = e.EdgeIntersectionList.Iterator(); eiIt.MoveNext();) { EdgeIntersection ei = (EdgeIntersection)eiIt.Current; RelateNode n = (RelateNode)nodes.AddNode(ei.coord); if (eLoc == LocationType.Boundary) { n.SetLabelBoundary(argIndex); } else { if (n.Label.IsNull(argIndex)) { n.SetLabel(argIndex, LocationType.Interior); } } } } }
} //void CreateEdgeEndForPrev(... /// <summary> /// Create a StubEdge for the edge after the intersection eiCurr. /// The next intersection is provided in case it is the endpoint for the stub edge. /// Otherwise, the next point from the parent edge will be the endpoint. /// eiCurr will always be an EdgeIntersection, but eiNext may be null. /// </summary> /// <param name="edge"></param> /// <param name="list"></param> /// <param name="eiCurr"></param> /// <param name="eiNext"></param> void CreateEdgeEndForNext( Edge edge, ArrayList list, EdgeIntersection eiCurr, EdgeIntersection eiNext) { int iNext = eiCurr.SegmentIndex + 1; // if there is no next edge there is nothing to do if (iNext >= edge.NumPoints && eiNext == null) { return; } Coordinate pNext = edge.GetCoordinate(iNext); // if the next intersection is in the same segment as the current, use it as the endpoint if (eiNext != null && eiNext.SegmentIndex == eiCurr.SegmentIndex) { pNext = eiNext.Coordinate; } EdgeEnd e = new EdgeEnd(edge, eiCurr.Coordinate, pNext, new Label(edge.Label)); //Trace.WriteLine( e.ToString() ); list.Add(e); } // void CreateEdgeEndForNext(...
/// <summary> /// Create a EdgeStub for the edge before the intersection eiCurr. /// The previous intersection is provided /// in case it is the endpoint for the stub edge. /// Otherwise, the previous point from the parent edge will be the endpoint. /// eiCurr will always be an EdgeIntersection, but eiPrev may be null. /// </summary> /// <param name="edge"></param> /// <param name="l"></param> /// <param name="eiCurr"></param> /// <param name="eiPrev"></param> public void CreateEdgeEndForPrev(Edge edge, IList <EdgeEnd> l, EdgeIntersection eiCurr, EdgeIntersection eiPrev) { int iPrev = eiCurr.SegmentIndex; if (eiCurr.Distance == 0.0) { // if at the start of the edge there is no previous edge if (iPrev == 0) { return; } iPrev--; } var pPrev = edge.GetCoordinate(iPrev); // if prev intersection is past the previous vertex, use it instead if (eiPrev != null && eiPrev.SegmentIndex >= iPrev) { pPrev = eiPrev.Coordinate; } var label = new Label(edge.Label); // since edgeStub is oriented opposite to it's parent edge, have to flip sides for edge label label.Flip(); var e = new EdgeEnd(edge, eiCurr.Coordinate, pPrev, label); l.Add(e); }
/// <summary> /// Creates stub edges for all the intersections in this /// Edge (if any) and inserts them into the graph. /// </summary> /// <param name="edge"></param> /// <param name="l"></param> public virtual void ComputeEdgeEnds(Edge edge, IList l) { EdgeIntersectionList eiList = edge.EdgeIntersectionList; // ensure that the list has entries for the first and last point of the edge eiList.AddEndpoints(); IEnumerator it = eiList.GetEnumerator(); EdgeIntersection eiCurr = null; // no intersections, so there is nothing to do if (!it.MoveNext()) { return; } EdgeIntersection eiNext = (EdgeIntersection)it.Current; do { EdgeIntersection eiPrev = eiCurr; eiCurr = eiNext; eiNext = null; if (it.MoveNext()) { eiNext = (EdgeIntersection)it.Current; } if (eiCurr != null) { CreateEdgeEndForPrev(edge, l, eiCurr, eiPrev); CreateEdgeEndForNext(edge, l, eiCurr, eiNext); } }while (eiCurr != null); }
/// <summary> /// Check that a ring does not self-intersect, except at its endpoints. /// Algorithm is to count the number of times each node along edge occurs. /// If any occur more than once, that must be a self-intersection. /// </summary> private void CheckNoSelfIntersectingRing(EdgeIntersectionList eiList) { ISet nodeSet = new HashedSet(); bool isFirst = true; for (IEnumerator i = eiList.Iterator(); i.MoveNext();) { EdgeIntersection ei = (EdgeIntersection)i.Current; if (isFirst) { isFirst = false; continue; } if (nodeSet.Contains(ei.coord)) { validErr = new ValidationError( ValidationErrorType.RingSelfIntersection, ei.coord); return; } else { nodeSet.Add(ei.coord); } } }
} // private void ComputeIntersectionNodes( int argIndex ) /// <summary> /// For all intersections on the edges of a Geometry, /// label the corresponding node IF it doesn't already have a label. /// This allows nodes created by either self-intersections or /// mutual intersections to be labelled. /// Endpoint nodes will already be labelled from when they were inserted. /// </summary> /// <param name="argIndex"></param> private void LabelIntersectionNodes(int argIndex) { foreach (object obj in _arg[argIndex].Edges) { Edge e = (Edge)obj; int eLoc = e.Label.GetLocation(argIndex); foreach (object objEdgeIntersection in e.EdgeIntersectionList) { EdgeIntersection ei = (EdgeIntersection)objEdgeIntersection; RelateNode n = (RelateNode)_nodes.Find(ei.Coordinate); if (n.Label.IsNull(argIndex)) { if (eLoc == Location.Boundary) { n.SetLabelBoundary(argIndex); } else { n.SetLabel(argIndex, Location.Interior); } } //Trace.WriteLine( n.ToString() ); } // foreach ( object objEdgeIntersection in e.EdgeIntersectionList ) } // foreach ( object obj in _arg[argIndex].Edges ) } // private void LabelIntersectionNodes( int argIndex )
/// <summary> /// Create a EdgeStub for the edge before the intersection eiCurr. /// The previous intersection is provided /// in case it is the endpoint for the stub edge. /// Otherwise, the previous point from the parent edge will be the endpoint. /// <br> /// eiCurr will always be an EdgeIntersection, but eiPrev may be null. /// </summary> internal void CreateEdgeEndForPrev(Edge edge, ArrayList l, EdgeIntersection eiCurr, EdgeIntersection eiPrev) { int iPrev = eiCurr.segmentIndex; if (eiCurr.dist == 0.0) { // if at the start of the edge there is no previous edge if (iPrev == 0) { return; } iPrev--; } Coordinate pPrev = edge.GetCoordinate(iPrev); // if prev intersection is past the previous vertex, use it instead if (eiPrev != null && eiPrev.segmentIndex >= iPrev) { pPrev = eiPrev.coord; } Label label = new Label(edge.Label); // since edgeStub is oriented opposite to it's parent edge, have to flip sides for edge label label.Flip(); EdgeEnd e = new EdgeEnd(edge, eiCurr.coord, pPrev, label); l.Add(e); }
} // public void Build(GeometryGraph geomGraph) /// <summary> /// Insert nodes for all intersections on the edges of a Geometry. /// Label the created nodes the same as the edge label if they do not already have a label. /// This allows nodes created by either self-intersections or /// mutual intersections to be labelled. /// Endpoint nodes will already be labelled from when they were inserted. /// Precondition: edge intersections have been computed. /// </summary> /// <param name="geomGraph"></param> /// <param name="argIndex"></param> public void ComputeIntersectionNodes(GeometryGraph geomGraph, int argIndex) { foreach (object obj in geomGraph.Edges) { Edge e = (Edge)obj; int eLoc = e.Label.GetLocation(argIndex); foreach (object objEdgeIntersection in e.EdgeIntersectionList) { EdgeIntersection ei = (EdgeIntersection)objEdgeIntersection; RelateNode n = (RelateNode)_nodes.AddNode(ei.Coordinate); if (eLoc == Location.Boundary) { n.SetLabelBoundary(argIndex); } else { if (n.Label.IsNull(argIndex)) { n.SetLabel(argIndex, Location.Interior); } // if ( n.Label.IsNull( argIndex ) ) } //Trace.WriteLine( n.ToString() ); } } // foreach ( object obj in geomGraph.Edges ) } // public void ComputeIntersectionNodes( GeometryGraph geomGraph, int argIndex )
} // public void ComputeEdgeEnds( Edge edge, ArrayList l ) /// <summary> /// Create a EdgeStub for the edge before the intersection eiCurr. /// The previous intersection is provided /// in case it is the endpoint for the stub edge. /// Otherwise, the previous point from the parent edge will be the endpoint. /// eiCurr will always be an EdgeIntersection, but eiPrev may be null. /// </summary> /// <param name="edge"></param> /// <param name="list"></param> /// <param name="eiCurr"></param> /// <param name="eiPrev"></param> void CreateEdgeEndForPrev( Edge edge, ArrayList list, EdgeIntersection eiCurr, EdgeIntersection eiPrev) { int iPrev = eiCurr.SegmentIndex; if (eiCurr.Distance == 0.0) { // if at the start of the edge there is no previous edge if (iPrev == 0) { return; } iPrev--; } Coordinate pPrev = edge.GetCoordinate(iPrev); // if prev intersection is past the previous vertex, use it instead if (eiPrev != null && eiPrev.SegmentIndex >= iPrev) { pPrev = eiPrev.Coordinate; } Label label = new Label(edge.Label); // since edgeStub is oriented opposite to it's parent edge, have to flip sides for edge label label.Flip(); EdgeEnd e = new EdgeEnd(edge, eiCurr.Coordinate, pPrev, label); //Trace.WriteLine( e.ToString() ); list.Add(e); } //void CreateEdgeEndForPrev(...
} // private bool IsSimpleLinearGeometry( Geometry geom ) /// <summary> /// For all edges, check if there are any intersections which are NOT at an endpoint. /// The Geometry is not simple if there are intersections not at endpoints. /// </summary> /// <param name="graph"></param> /// <returns></returns> private bool HasNonEndpointIntersection(GeometryGraph graph) { foreach (object obj in graph.Edges) { Edge e = (Edge)obj; int maxSegmentIndex = e.MaximumSegmentIndex; foreach (object eiObj in e.EdgeIntersectionList) { EdgeIntersection ei = (EdgeIntersection)eiObj; if (!ei.IsEndPoint(maxSegmentIndex)) { return(true); } } } // foreach ( object obj in graph.Edges ) return(false); } // private bool HasNonEndpointIntersection(GeometryGraph graph)
/// <summary> /// For all edges, check if there are any intersections which are NOT at an endpoint. /// The Geometry is not simple if there are intersections not at endpoints. /// </summary> /// <param name="graph"></param> private bool HasNonEndpointIntersection(GeometryGraph graph) { for (IEnumerator i = graph.GetEdgeEnumerator(); i.MoveNext();) { Edge e = (Edge)i.Current; int maxSegmentIndex = e.MaximumSegmentIndex; for (IEnumerator eiIt = e.EdgeIntersectionList.GetEnumerator(); eiIt.MoveNext();) { EdgeIntersection ei = (EdgeIntersection)eiIt.Current; if (!ei.IsEndPoint(maxSegmentIndex)) { return(true); } } } return(false); }
/// <summary> /// For all intersections on the edges of a Geometry, /// label the corresponding node IF it doesn't already have a label. /// This allows nodes created by either self-intersections or /// mutual intersections to be labelled. /// Endpoint nodes will already be labelled from when they were inserted. /// </summary> /// <param name="argIndex"></param> private void LabelIntersectionNodes(int argIndex) { for (IEnumerator i = arg[argIndex].GetEdgeEnumerator(); i.MoveNext(); ) { Edge e = (Edge)i.Current; Locations eLoc = e.Label.GetLocation(argIndex); for (IEnumerator eiIt = e.EdgeIntersectionList.GetEnumerator(); eiIt.MoveNext(); ) { EdgeIntersection ei = (EdgeIntersection)eiIt.Current; RelateNode n = (RelateNode)nodes.Find(ei.Coordinate); if (n.Label.IsNull(argIndex)) { if (eLoc == Locations.Boundary) n.SetLabelBoundary(argIndex); else n.SetLabel(argIndex, Locations.Interior); } } } }
/// <summary> /// Insert nodes for all intersections on the edges of a Geometry. /// Label the created nodes the same as the edge label if they do not already have a label. /// This allows nodes created by either self-intersections or /// mutual intersections to be labelled. /// Endpoint nodes will already be labelled from when they were inserted. /// Precondition: edge intersections have been computed. /// </summary> /// <param name="geomGraph"></param> /// <param name="argIndex"></param> public virtual void ComputeIntersectionNodes(GeometryGraph geomGraph, int argIndex) { for (IEnumerator edgeIt = geomGraph.GetEdgeEnumerator(); edgeIt.MoveNext();) { Edge e = (Edge)edgeIt.Current; Locations eLoc = e.Label.GetLocation(argIndex); for (IEnumerator eiIt = e.EdgeIntersectionList.GetEnumerator(); eiIt.MoveNext();) { EdgeIntersection ei = (EdgeIntersection)eiIt.Current; RelateNode n = (RelateNode)nodes.AddNode(ei.Coordinate); if (eLoc == Locations.Boundary) { n.SetLabelBoundary(argIndex); } else if (n.Label.IsNull(argIndex)) { n.SetLabel(argIndex, Locations.Interior); } } } }
} // public ArrayList ComputeEdgeEnds( ArrayList edges ) /// <summary> /// Creates stub edges for all the intersections in this Edge (if any) and inserts them into the graph. /// </summary> /// <param name="edge"></param> /// <param name="list"></param> public void ComputeEdgeEnds(Edge edge, ArrayList list) { EdgeIntersectionList eiList = edge.EdgeIntersectionList; //Trace.WriteLine( eiList.ToString() ); // ensure that the list has entries for the first and last point of the edge if (!edge.IsClosed) { eiList.AddEndpoints(); } EdgeIntersection eiPrev = null; EdgeIntersection eiCurr = null; // no intersections, so there is nothing to do if (eiList.IsEmpty()) { return; // return if the list is empty } int index = 0; // index of eiList array. EdgeIntersection eiNext = eiList[index]; // gets the first intersection do { index++; eiPrev = eiCurr; // previouse one or null for first loop eiCurr = eiNext; // current one or the first one eiNext = null; if (index < eiList.Count) { eiNext = eiList[index]; // if there are more } if (eiCurr != null) { CreateEdgeEndForPrev(edge, list, eiCurr, eiPrev); CreateEdgeEndForNext(edge, list, eiCurr, eiNext); } } while (eiCurr != null); } // public void ComputeEdgeEnds( Edge edge, ArrayList l )
/// <summary> /// Create a StubEdge for the edge after the intersection eiCurr. /// The next intersection is provided /// in case it is the endpoint for the stub edge. /// Otherwise, the next point from the parent edge will be the endpoint. /// eiCurr will always be an EdgeIntersection, but eiNext may be null. /// </summary> /// <param name="edge"></param> /// <param name="l"></param> /// <param name="eiCurr"></param> /// <param name="eiNext"></param> public virtual void CreateEdgeEndForNext(Edge edge, IList l, EdgeIntersection eiCurr, EdgeIntersection eiNext) { int iNext = eiCurr.SegmentIndex + 1; // if there is no next edge there is nothing to do if (iNext >= edge.NumPoints && eiNext == null) { return; } Coordinate pNext = edge.GetCoordinate(iNext); // if the next intersection is in the same segment as the current, use it as the endpoint if (eiNext != null && eiNext.SegmentIndex == eiCurr.SegmentIndex) { pNext = eiNext.Coordinate; } EdgeEnd e = new EdgeEnd(edge, eiCurr.Coordinate, pNext, new Label(edge.Label)); l.Add(e); }
/// <summary> /// Insert nodes for all intersections on the edges of a Geometry. /// Label the created nodes the same as the edge label if they do not already have a label. /// This allows nodes created by either self-intersections or /// mutual intersections to be labelled. /// Endpoint nodes will already be labelled from when they were inserted. /// </summary> /// <param name="argIndex"></param> private void ComputeIntersectionNodes(int argIndex) { for (IEnumerator i = _arg[argIndex].GetEdgeEnumerator(); i.MoveNext();) { Edge e = (Edge)i.Current; LocationType eLoc = e.Label.GetLocation(argIndex); for (IEnumerator eiIt = e.EdgeIntersectionList.GetEnumerator(); eiIt.MoveNext();) { EdgeIntersection ei = (EdgeIntersection)eiIt.Current; RelateNode n = (RelateNode)_nodes.AddNode(ei.Coordinate); if (eLoc == LocationType.Boundary) { n.SetLabelBoundary(argIndex); } else { if (n.Label.IsNull(argIndex)) { n.SetLabel(argIndex, LocationType.Interior); } } } } }
private static Tuple<int[], EdgeIntersection[]>[] GetIslandsSprtIndices(Point[][] polygons, EdgeIntersection[] intersections) { List<Tuple<int[], EdgeIntersection[]>> retVal = new List<Tuple<int[], EdgeIntersection[]>>(); List<int> remaining = Enumerable.Range(0, polygons.Length).ToList(); while (remaining.Count > 0) { // Find all the polygons that are touching this one var currentIsland = GetIslandsSprtTouching(remaining[0], intersections); // Remove these from the remaining list (after this, what's in remaining are polygons that aren't touching what's in retVal) foreach (int index in currentIsland.Item1) { remaining.Remove(index); } // Store this island retVal.Add(currentIsland); } // Exit Function return retVal.ToArray(); }
/// <summary> /// Adds an intersection into the list, if it isn't already there. /// The input segmentIndex and distance are expected to be normalized. /// </summary> /// <param name="coord"></param> /// <param name="segmentIndex"></param> /// <param name="distance"></param> /// <returns>return the EdgeIntersection found or added</returns> public EdgeIntersection Add(Coordinate coord, int segmentIndex, double distance) { // this varies from the java code due to the differences in arraylist. java can add based on the // iterator. int indexAt; bool isInList = FindInsertionPoint( segmentIndex, distance, out indexAt ); EdgeIntersection ei; if ( !isInList ) { ei = new EdgeIntersection(coord, segmentIndex, distance); if ( indexAt < 0 ) // not found and greater than all others in list. { _list.Add( ei ); } else { _list.Insert( indexAt, ei ); // not found but insert at this index to keep order. } } else { ei = (EdgeIntersection)_list[indexAt]; // found in list at this index. } return ei; }
/// <summary> /// Create a new "split edge" with the section of points between /// (and including) the two intersections. /// The label for the new edge is the same as the label for the parent edge. /// </summary> private Edge CreateSplitEdge(EdgeIntersection ei0, EdgeIntersection ei1) { //Trace.WriteLine("\ncreateSplitEdge"); Trace.WriteLine(ei0.ToString()); Trace.WriteLine(ei1.ToString()); int npts = ei1.SegmentIndex - ei0.SegmentIndex + 2; Coordinate lastSegStartPt = _edge.Coordinates[ ei1.SegmentIndex ]; // if the last intersection point is not equal to the its segment start pt, // add it to the points list as well. // (This check is needed because the distance metric is not totally reliable!) bool useIntPt1 = ei1.Distance > 0.0 || ! ei1.Coordinate.Equals( lastSegStartPt ); Coordinates coordinatePts = new Coordinates(); // new coordinates collection coordinatePts.Add( new Coordinate( ei0.Coordinate ) ); for (int i = ei0.SegmentIndex + 1; i <= ei1.SegmentIndex; i++) { coordinatePts.Add( _edge.Coordinates[i] ); } if ( useIntPt1 ) { coordinatePts.Add( ei1.Coordinate ); } return new Edge( coordinatePts, new Label( _edge.Label )); }
private static EdgeIntersection[] MergeIslandSprtSegmentsSprtIntersections(int polygonIndex, Edge2D edge, EdgeIntersection[] intersections) { List<EdgeIntersection> retVal = new List<EdgeIntersection>(); foreach (EdgeIntersection intersection in intersections) { if (intersection.Poly1Index == polygonIndex) // polygon match (1) { if (MergeIslandSprtSegmentsSprtIntersectionsSprtIsSame(edge.Index0, edge.Index1.Value, intersection.Poly1Edge.Index0, intersection.Poly1Edge.Index1.Value)) // edge match (1) { retVal.Add(intersection); } } else if (intersection.Poly2Index == polygonIndex) // polygon match (2) { if (MergeIslandSprtSegmentsSprtIntersectionsSprtIsSame(edge.Index0, edge.Index1.Value, intersection.Poly2Edge.Index0, intersection.Poly2Edge.Index1.Value)) // edge match (2) { retVal.Add(intersection); } } } return retVal.ToArray(); }
private static IEnumerable<Tuple<Point, Point>> MergeIslandSprtSegmentsSprtDivide_OLD(int polyCntr, Edge2D edge, EdgeIntersection[] intersections) { // Build vectors from edge.p0 to each intersection, sort by length var distances = Enumerable.Range(0, intersections.Length). Select(o => new { Index = o, Distance = (intersections[o].IntersectionPoint - edge.Point0).LengthSquared }). OrderBy(o => o.Distance). ToArray(); List<Tuple<Point, Point>> retVal = new List<Tuple<Point, Point>>(); // Point0 to first intersect retVal.Add(Tuple.Create( edge.Point0, intersections[distances[0].Index].IntersectionPoint)); // Intersect to Intersect for (int cntr = 0; cntr < distances.Length - 1; cntr++) { retVal.Add(Tuple.Create( intersections[distances[cntr].Index].IntersectionPoint, intersections[distances[cntr + 1].Index].IntersectionPoint)); } // Last intersect to Point1 retVal.Add(Tuple.Create( intersections[distances[distances.Length - 1].Index].IntersectionPoint, edge.Point1Ext)); return retVal; }
public PolygonIsland(Point[][] polygons, EdgeIntersection[] intersections) { this.Polygons = polygons; this.Intersections = intersections; }
private static PolygonIsland[] GetIslands(Point[][] polygons, EdgeIntersection[] intersections) { // Figure out which polygons are in which islands var islands = GetIslandsSprtIndices(polygons, intersections); if (islands.Length == 1) { return new PolygonIsland[] { new PolygonIsland(polygons, intersections) }; } PolygonIsland[] retVal = new PolygonIsland[islands.Length]; // Make new intersections that only know about the polygons in their island for (int cntr = 0; cntr < retVal.Length; cntr++) { List<Point[]> localPolys = new List<Point[]>(); SortedList<int, int> mapping = new SortedList<int, int>(); foreach (int index in islands[cntr].Item1) { mapping.Add(index, localPolys.Count); localPolys.Add(polygons[index]); } EdgeIntersection[] localIntersections = islands[cntr].Item2.Select(o => new EdgeIntersection(mapping[o.Poly1Index], o.Poly1Edge, mapping[o.Poly2Index], o.Poly2Edge, o.IntersectionPoint)).ToArray(); retVal[cntr] = new PolygonIsland(localPolys.ToArray(), localIntersections); } // Exit Function return retVal; }
} //void CreateEdgeEndForPrev(... /// <summary> /// Create a StubEdge for the edge after the intersection eiCurr. /// The next intersection is provided in case it is the endpoint for the stub edge. /// Otherwise, the next point from the parent edge will be the endpoint. /// eiCurr will always be an EdgeIntersection, but eiNext may be null. /// </summary> /// <param name="edge"></param> /// <param name="list"></param> /// <param name="eiCurr"></param> /// <param name="eiNext"></param> void CreateEdgeEndForNext( Edge edge, ArrayList list, EdgeIntersection eiCurr, EdgeIntersection eiNext) { int iNext = eiCurr.SegmentIndex + 1; // if there is no next edge there is nothing to do if ( iNext >= edge.NumPoints && eiNext == null ) return; Coordinate pNext = edge.GetCoordinate( iNext ); // if the next intersection is in the same segment as the current, use it as the endpoint if ( eiNext != null && eiNext.SegmentIndex == eiCurr.SegmentIndex ) { pNext = eiNext.Coordinate; } EdgeEnd e = new EdgeEnd( edge, eiCurr.Coordinate, pNext, new Label( edge.Label ) ); //Trace.WriteLine( e.ToString() ); list.Add( e ); } // void CreateEdgeEndForNext(...
private static Tuple<int[], EdgeIntersection[]> GetIslandsSprtTouching(int index, EdgeIntersection[] intersections) { List<int> returnIndices = new List<int>(); List<EdgeIntersection> returnIntersections = new List<EdgeIntersection>(); Stack<int> newIndices = new Stack<int>(); // Put the intersections in a list, so it can be removed from as matches are found List<EdgeIntersection> remainingIntersections = intersections.ToList(); // Start the working stack off with the index passed in newIndices.Push(index); while (newIndices.Count > 0) { // Pop off the stack, and look for matches int currentIndex = newIndices.Pop(); returnIndices.Add(currentIndex); // Find unique intersections that match this current polygon, and put them in the working stack if they haven't been encountered yet foreach (int match in GetIslandsSprtTouchingSprtExamine(remainingIntersections, returnIntersections, currentIndex)) { if (!returnIndices.Contains(match) && !newIndices.Contains(match)) { newIndices.Push(match); } } } // Exit Function return Tuple.Create(returnIndices.ToArray(), returnIntersections.ToArray()); }
} // public void ComputeEdgeEnds( Edge edge, ArrayList l ) /// <summary> /// Create a EdgeStub for the edge before the intersection eiCurr. /// The previous intersection is provided /// in case it is the endpoint for the stub edge. /// Otherwise, the previous point from the parent edge will be the endpoint. /// eiCurr will always be an EdgeIntersection, but eiPrev may be null. /// </summary> /// <param name="edge"></param> /// <param name="list"></param> /// <param name="eiCurr"></param> /// <param name="eiPrev"></param> void CreateEdgeEndForPrev( Edge edge, ArrayList list, EdgeIntersection eiCurr, EdgeIntersection eiPrev) { int iPrev = eiCurr.SegmentIndex; if ( eiCurr.Distance == 0.0 ) { // if at the start of the edge there is no previous edge if ( iPrev == 0 ) return; iPrev--; } Coordinate pPrev = edge.GetCoordinate( iPrev ); // if prev intersection is past the previous vertex, use it instead if ( eiPrev != null && eiPrev.SegmentIndex >= iPrev ) { pPrev = eiPrev.Coordinate; } Label label = new Label( edge.Label ); // since edgeStub is oriented opposite to it's parent edge, have to flip sides for edge label label.Flip(); EdgeEnd e = new EdgeEnd( edge, eiCurr.Coordinate, pPrev, label ); //Trace.WriteLine( e.ToString() ); list.Add( e ); } //void CreateEdgeEndForPrev(...