Example #1
0
        /// <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);
                        }
                    }
                }
            }
        }
Example #2
0
        }          //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(...
Example #3
0
        /// <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);
        }
Example #4
0
        /// <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);
        }
Example #5
0
        /// <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);
                }
            }
        }
Example #6
0
        }         // 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 )
Example #7
0
        /// <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);
        }
Example #8
0
        }         // 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 )
Example #9
0
        }         // 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(...
Example #10
0
        }         // 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)
Example #11
0
 /// <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);
 }
Example #12
0
 /// <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);
             }
         }
     }
 }
Example #13
0
 /// <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);
             }
         }
     }
 }
Example #14
0
        }         // 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 )
Example #15
0
        /// <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);
        }
Example #16
0
 /// <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();
            }
Example #18
0
 /// <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;
 }
Example #19
0
        /// <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;
            }
Example #24
0
		}  //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());
            }
Example #26
0
		} // 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(...