Пример #1
0
        }         // public PolygonBuilder( GeometryFactory geometryFactory, CGAlgorithms cga )

        #endregion

        #region Properties
        #endregion

        #region Methods

        /// <summary>
        /// Add a complete graph.
        /// The graph is assumed to contain one or more polygons,
        /// possibly with holes.
        /// </summary>
        /// <param name="graph"></param>
        public void Add(PlanarGraph graph)
        {
            ArrayList nodes = new ArrayList();

            foreach (DictionaryEntry entry in graph.Nodes.NodeList)
            {
                Node node = (Node)entry.Value;
                nodes.Add(node);
            }
            Add(graph.EdgeEnds, nodes);
        }         // public void Add( PlanarGraph graph )
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="g0"></param>
        /// <param name="g1"></param>
        public OverlayOp(IGeometry g0, IGeometry g1) : base(g0, g1)
        {
            graph = new PlanarGraph(new OverlayNodeFactory());

            /*
             * Use factory of primary point.
             * Note that this does NOT handle mixed-precision arguments
             * where the second arg has greater precision than the first.
             */
            geomFact = g0.Factory;
        }
Пример #3
0
        /// <summary>
        /// Add a set of edges and nodes, which form a graph.
        /// The graph is assumed to contain one or more polygons,
        /// possibly with holes.
        /// </summary>
        /// <param name="dirEdges"></param>
        /// <param name="nodes"></param>
        public void Add(IList dirEdges, IList nodes)
        {
            PlanarGraph.LinkResultDirectedEdges(nodes);
            IList maxEdgeRings = BuildMaximalEdgeRings(dirEdges);
            IList freeHoleList = new ArrayList();
            IList edgeRings    = BuildMinimalEdgeRings(maxEdgeRings, shellList, freeHoleList);

            SortShellsAndHoles(edgeRings, shellList, freeHoleList);
            PlaceFreeHoles(shellList, freeHoleList);
            //Assert: every hole on freeHoleList has a shell assigned to it
        }
        /// <summary>
        /// Add a set of edges and nodes, which form a graph.
        /// The graph is assumed to contain one or more polygons,
        /// possibly with holes.
        /// </summary>
        /// <param name="dirEdges"></param>
        /// <param name="nodes"></param>
        public void Add(IList <EdgeEnd> dirEdges, IList <Node> nodes)
        {
            PlanarGraph.LinkResultDirectedEdges(nodes);
            var maxEdgeRings = BuildMaximalEdgeRings(dirEdges);
            var freeHoleList = new List <EdgeRing>();
            var edgeRings    = BuildMinimalEdgeRings(maxEdgeRings, _shellList, freeHoleList);

            SortShellsAndHoles(edgeRings, _shellList, freeHoleList);
            PlaceFreeHoles(_shellList, freeHoleList);
            //Assert: every hole on freeHoleList has a shell assigned to it
        }
Пример #5
0
        public IGeometry Buffer(IGeometry g, double distance)
        {
            IPrecisionModel precisionModel = _workingPrecisionModel;

            if (precisionModel == null)
            {
                precisionModel = g.PrecisionModel;
            }

            // factory must be the same as the one used by the input
            _geomFact = g.Factory;

            OffsetCurveBuilder curveBuilder = new OffsetCurveBuilder(precisionModel, _bufParams);

            OffsetCurveSetBuilder curveSetBuilder = new OffsetCurveSetBuilder(g, distance, curveBuilder);

            var bufferSegStrList = curveSetBuilder.GetCurves();

            // short-circuit test
            if (bufferSegStrList.Count <= 0)
            {
                return(CreateEmptyResultGeometry());
            }

            //BufferDebug.runCount++;
            //String filename = "run" + BufferDebug.runCount + "_curves";
            //System.out.println("saving " + filename);
            //BufferDebug.saveEdges(bufferEdgeList, filename);
            // DEBUGGING ONLY
            //WKTWriter wktWriter = new WKTWriter();
            //Debug.println("Rings: " + wktWriter.write(convertSegStrings(bufferSegStrList.iterator())));
            //wktWriter.setMaxCoordinatesPerLine(10);
            //System.out.println(wktWriter.writeFormatted(convertSegStrings(bufferSegStrList.iterator())));

            ComputeNodedEdges(bufferSegStrList, precisionModel);
            _graph = new PlanarGraph(new OverlayNodeFactory());
            _graph.AddEdges(_edgeList.Edges);

            IEnumerable <BufferSubgraph> subgraphList = CreateSubgraphs(_graph);
            PolygonBuilder polyBuilder = new PolygonBuilder(_geomFact);

            BuildSubgraphs(subgraphList, polyBuilder);
            var resultPolyList = polyBuilder.Polygons;

            // just in case...
            if (resultPolyList.Count <= 0)
            {
                return(CreateEmptyResultGeometry());
            }

            IGeometry resultGeom = _geomFact.BuildGeometry(resultPolyList);

            return(resultGeom);
        }
Пример #6
0
 private void SetInteriorEdgesInResult(PlanarGraph graph)
 {
     for (IEnumerator it = graph.EdgeEnds.GetEnumerator();
          it.MoveNext();)
     {
         DirectedEdge de = (DirectedEdge)it.Current;
         if (de.Label.GetLocation(0, Position.Right) ==
             LocationType.Interior)
         {
             de.InResult = true;
         }
     }
 }
Пример #7
0
        private static void getCutsAndDangles(PlanarGraph graph,
                                              out IList <Segment> dangles)
        {
            dangles = new List <Segment>();

            foreach (PlanarGraphEdge edge in graph.Edges)
            {
                if (edge.Label.Tag == _dangleLabelTag)
                {
                    dangles.Add(new Segment(edge.Node1.Point, edge.Node2.Point));
                }
            }
        }
Пример #8
0
 /// <summary>
 /// Mark all the edges for the edgeRings corresponding to the shells of the input polygons.
 /// Only ONE ring gets marked for each shell - if there are others which remain unmarked
 /// this indicates a disconnected interior.
 /// </summary>
 /// <param name="g"></param>
 /// <param name="graph"></param>
 private void VisitShellInteriors(IGeometry g, PlanarGraph graph)
 {
     if (g is Polygon)
     {
         Polygon p = (Polygon)g;
         VisitInteriorRing(p.ExteriorRing, graph);
     }
     if (g is MultiPolygon)
     {
         MultiPolygon mp = (MultiPolygon)g;
         foreach (Polygon p in mp.Geometries)
         {
             VisitInteriorRing(p.ExteriorRing, graph);
         }
     }
 }
 /// <summary>
 /// Mark all the edges for the edgeRings corresponding to the shells of the input polygons.
 /// Only ONE ring gets marked for each shell - if there are others which remain unmarked
 /// this indicates a disconnected interior.
 /// </summary>
 /// <param name="g"></param>
 /// <param name="graph"></param>
 private void VisitShellInteriors(IGeometry g, PlanarGraph graph)
 {
     if (g is IPolygon)
     {
         IPolygon p = (IPolygon)g;
         VisitInteriorRing(p.Shell, graph);
     }
     if (g is IMultiPolygon)
     {
         IMultiPolygon mp = (IMultiPolygon)g;
         foreach (IPolygon p in mp.Geometries)
         {
             VisitInteriorRing(p.Shell, graph);
         }
     }
 }
Пример #10
0
        private static int MinDistToMapEdge(PlanarGraph graph, Node n, int limit)
        {
            if (n.Coordinate.X == 0 || n.Coordinate.X == Size ||
                n.Coordinate.Y == 0 || n.Coordinate.Y == Size)
            {
                return(0);
            }

            int ret = int.MaxValue;
            Stack <Tuple <int, Node> > stack   = new Stack <Tuple <int, Node> >();
            HashSet <Node>             visited = new HashSet <Node>();

            stack.Push(new Tuple <int, Node>(0, n));
            do
            {
                Tuple <int, Node> state = stack.Pop();
                if (state.Item2.Coordinate.X == 0 || state.Item2.Coordinate.X == Size ||
                    state.Item2.Coordinate.Y == 0 || state.Item2.Coordinate.Y == Size)
                {
                    if (state.Item1 < ret)
                    {
                        ret = state.Item1;
                    }
                    if (ret == 0)
                    {
                        return(0);
                    }

                    continue;
                }
                visited.Add(state.Item2);

                if (state.Item1 > limit)
                {
                    continue;
                }
                foreach (EdgeEnd i in state.Item2.Edges)
                {
                    Node node = graph.Find(i.DirectedCoordinate);
                    if (!visited.Contains(node))
                    {
                        stack.Push(new Tuple <int, Node>(state.Item1 + 1, node));
                    }
                }
            } while (stack.Count > 0);
            return(ret);
        }
Пример #11
0
 /// <summary>
 ///  Mark all the edges for the edgeRings corresponding to the shells
 ///  of the input polygons.  Note only ONE ring gets marked for each shell.
 /// </summary>
 /// <param name="g"></param>
 /// <param name="graph"></param>
 private void VisitShellInteriors(Geometry g, PlanarGraph graph)
 {
     if (g is Polygon)
     {
         Polygon p = (Polygon)g;
         this.VisitInteriorRing(p.GetExteriorRing(), graph);
     }
     if (g is MultiPolygon)
     {
         MultiPolygon mp = (MultiPolygon)g;
         for (int i = 0; i < mp.GetNumGeometries(); i++)
         {
             Polygon p = (Polygon)mp.GetGeometryN(i);
             this.VisitInteriorRing(p.GetExteriorRing(), graph);
         }
     }
 }
Пример #12
0
        private static void build(
            out IList <Polygon> result,
            out IList <Segment> dangles,
            out IList <Segment> cuts)
        {
            Polyline polyline = new Polyline();

            polyline.Paths = _sourcePaths;

            PlanarGraph graph = PlanarGraph.Build(polyline, null);

            graph.SetElementsEnabledState(true);

            markDangles(graph);
            getCutsAndDangles(graph, out dangles);

            result = graph.BuildFaces(out cuts);
        }
Пример #13
0
        public IGeometry Buffer(IGeometry g, double distance)
        {
            IPrecisionModel precisionModel = _workingPrecisionModel;

            if (precisionModel == null)
            {
                precisionModel = g.PrecisionModel;
            }

            // factory must be the same as the one used by the input
            _geomFact = g.Factory;

            OffsetCurveBuilder curveBuilder = new OffsetCurveBuilder(precisionModel, _bufParams);

            OffsetCurveSetBuilder curveSetBuilder = new OffsetCurveSetBuilder(g, distance, curveBuilder);

            var bufferSegStrList = curveSetBuilder.GetCurves();

            // short-circuit test
            if (bufferSegStrList.Count <= 0)
            {
                return(CreateEmptyResultGeometry());
            }

            ComputeNodedEdges(bufferSegStrList, precisionModel);
            _graph = new PlanarGraph(new OverlayNodeFactory());
            _graph.AddEdges(_edgeList.Edges);

            IEnumerable <BufferSubgraph> subgraphList = CreateSubgraphs(_graph);
            PolygonBuilder polyBuilder = new PolygonBuilder(_geomFact);

            BuildSubgraphs(subgraphList, polyBuilder);
            var resultPolyList = polyBuilder.Polygons;

            // just in case...
            if (resultPolyList.Count <= 0)
            {
                return(CreateEmptyResultGeometry());
            }

            IGeometry resultGeom = _geomFact.BuildGeometry(resultPolyList);

            return(resultGeom);
        }
        public static void TestCountOfEdges(int maxN)
        {
            int right = 0;

            for (int i = 3; i <= maxN; i++)
            {
                PlanarGraph pg = CreateGridAndTriangulation(i);
                if (pg.planarEdges.Count != 3 * (pg.planarNodes.Count - 2))
                {
                    Console.WriteLine("Error for N=" + i + ". |E|=" + pg.planarEdges.Count);
                }
                else
                {
                    right++;
                }
            }
            Console.WriteLine("Correct " + right + " out of " + (maxN - 2));
            Console.ReadKey();
        }
Пример #15
0
        private static void markDangles(PlanarGraph graph)
        {
            Stack <PlanarGraphNode> nodeStack = new Stack <PlanarGraphNode>();

            // find sites with a single incident to and put them on the stack
            foreach (PlanarGraphNode node in graph.Nodes)
            {
                if (node.IncidentEdges.Count == 1)
                {
                    nodeStack.Push(node);
                }
            }

            while (nodeStack.Count > 0)
            {
                PlanarGraphNode node = nodeStack.Pop();
                node.Enabled = false;

                PlanarGraphEdge enabledEdge = getSingleEnabledEdge(node);

                // there was one available edge
                if (enabledEdge != null)
                {
                    enabledEdge.Enabled   = false;
                    enabledEdge.Label.Tag = _dangleLabelTag;
                    if (enabledEdge.Node1 == node)
                    {
                        if (getSingleEnabledEdge(enabledEdge.Node2) != null)
                        {
                            nodeStack.Push(enabledEdge.Node2);
                        }
                    }
                    else
                    {
                        if (getSingleEnabledEdge(enabledEdge.Node1) != null)
                        {
                            nodeStack.Push(enabledEdge.Node1);
                        }
                    }
                }
            }
        }
Пример #16
0
		public virtual Geometry Buffer(Geometry g, double distance)
		{
			PrecisionModel precisionModel = workingPrecisionModel;
			if (precisionModel == null)
				precisionModel = g.PrecisionModel;
			
			// factory must be the same as the one used by the input
			geomFact = g.Factory;
			
			OffsetCurveBuilder curveBuilder = 
                new OffsetCurveBuilder(precisionModel, quadrantSegments);
			curveBuilder.EndCapStyle = endCapStyle;

			OffsetCurveSetBuilder curveSetBuilder = 
                new OffsetCurveSetBuilder(g, distance, curveBuilder);
			
			ArrayList bufferSegStrList = curveSetBuilder.Curves;
			
			// short-circuit test
			if (bufferSegStrList.Count <= 0)
			{
				Geometry emptyGeom = 
                    geomFact.CreateGeometryCollection(new Geometry[0]);

				return emptyGeom;
			}
			
			ComputeNodedEdges(bufferSegStrList, precisionModel);
			graph = new PlanarGraph(new OverlayNodeFactory());
			graph.AddEdges(edgeList.Edges);
			
			IList subgraphList         = CreateSubgraphs(graph);
			PolygonBuilder polyBuilder = new PolygonBuilder(geomFact);
			
            BuildSubgraphs(subgraphList, polyBuilder);

			GeometryList resultPolyList = polyBuilder.Build();
			
			Geometry resultGeom = geomFact.BuildGeometry(resultPolyList);

			return resultGeom;
		}
Пример #17
0
        private void VisitInteriorRing(ILineString iring, PlanarGraph graph)
        {
            LineString   ring  = (LineString)iring;
            Coordinates  pts   = ring.GetCoordinates();
            Edge         e     = graph.FindEdgeInSameDirection(pts[0], pts[1]);
            DirectedEdge de    = (DirectedEdge)graph.FindEdgeEnd(e);
            DirectedEdge intDe = null;

            if (de.Label.GetLocation(0, Position.Right) == Location.Interior)
            {
                intDe = de;
            }
            else if (de.Sym.Label.GetLocation(0, Position.Right) == Location.Interior)
            {
                intDe = de.Sym;
            }
            //Assert.isTrue(intDe != null, "unable to find dirEdge with Interior on RHS");

            VisitLinkedDirectedEdges(intDe);
        }
Пример #18
0
        /// <summary>
        /// Mark all the edges for the edgeRings corresponding to the shells
        /// of the input polygons.
        /// Only ONE ring gets marked for each shell - if there are others which remain unmarked
        /// this indicates a disconnected interior.
        /// </summary>
        private void VisitShellInteriors(Geometry g, PlanarGraph graph)
        {
            GeometryType geomType = g.GeometryType;

            if (geomType == GeometryType.Polygon)
            {
                Polygon p = (Polygon)g;
                VisitInteriorRing(p.ExteriorRing, graph);
            }

            if (geomType == GeometryType.MultiPolygon)
            {
                MultiPolygon mp = (MultiPolygon)g;
                for (int i = 0; i < mp.NumGeometries; i++)
                {
                    Polygon p = (Polygon)mp.GetGeometry(i);
                    VisitInteriorRing(p.ExteriorRing, graph);
                }
            }
        }
Пример #19
0
 private static IEnumerable<BufferSubgraph> CreateSubgraphs(PlanarGraph graph)
 {
     var subgraphList = new List<BufferSubgraph>();
     foreach (Node node in graph.Nodes)
     {
         if (!node.IsVisited)
         {
             var subgraph = new BufferSubgraph();
             subgraph.Create(node);
             subgraphList.Add(subgraph);
         }
     }
     /*
      * Sort the subgraphs in descending order of their rightmost coordinate.
      * This ensures that when the Polygons for the subgraphs are built,
      * subgraphs for shells will have been built before the subgraphs for
      * any holes they contain.
      */
     subgraphList.Sort();
     subgraphList.Reverse();
     return subgraphList;
 }
Пример #20
0
        private void VisitInteriorRing(LineString ring, PlanarGraph graph)
        {
            ICoordinateList pts = ring.Coordinates;
            Coordinate      pt0 = pts[0];
            // Find first point in coord list different to initial point.
            // Need special check since the first point may be repeated.
            Coordinate   pt1   = FindDifferentPoint(pts, pt0);
            Edge         e     = graph.FindEdgeInSameDirection(pt0, pt1);
            DirectedEdge de    = (DirectedEdge)graph.FindEdgeEnd(e);
            DirectedEdge intDe = null;

            if (de.Label.GetLocation(0, Position.Right) == LocationType.Interior)
            {
                intDe = de;
            }
            else if (de.Sym.Label.GetLocation(0, Position.Right) == LocationType.Interior)
            {
                intDe = de.Sym;
            }
            Debug.Assert(intDe != null, "unable to find dirEdge with Interior on RHS");

            VisitLinkedDirectedEdges(intDe);
        }
Пример #21
0
        public OverlayOp(Geometry g0, Geometry g1) : base(g0, g1)
		{
            if (g0 == null)
            {
                throw new ArgumentNullException("g0");
            }
            if (g1 == null)
            {
                throw new ArgumentNullException("g1");
            }

            ptLocator       = new PointLocator();
            edgeList        = new EdgeList();
            resultPolyList  = new GeometryList();
            resultLineList  = new GeometryList();
            resultPointList = new GeometryList();

			graph = new PlanarGraph(new OverlayNodeFactory());
			// Use factory of primary geometry.
			// Note that this does NOT handle mixed-precision arguments
			// where the second arg has greater precision than the first.
			geomFact = g0.Factory;
		}
Пример #22
0
		private IList CreateSubgraphs(PlanarGraph graph)
		{
			ArrayList subgraphList = new ArrayList();

            for (IEnumerator i = graph.Nodes.GetEnumerator(); i.MoveNext(); )
			{
				Node node = (Node) i.Current;
				if (!node.Visited)
				{
					BufferSubgraph subgraph = new BufferSubgraph();
					subgraph.Create(node);

                    subgraphList.Add(subgraph);
				}
			}

			// Sort the subgraphs in descending order of their rightmost coordinate.
			// This ensures that when the Polygons for the subgraphs are built,
			// subgraphs for shells will have been built before the subgraphs for
			// any holes they contain.
            subgraphList.Sort(new ReverseComparator());

			return subgraphList;
		}
Пример #23
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="g"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public IGeometry Buffer(IGeometry g, double distance)
        {
            var precisionModel = workingPrecisionModel ?? g.PrecisionModel;

            // factory must be the same as the one used by the input
            geomFact = g.Factory;

            var curveBuilder = new OffsetCurveBuilder(precisionModel, quadrantSegments)
            {
                EndCapStyle = endCapStyle
            };
            var curveSetBuilder = new OffsetCurveSetBuilder(g, distance, curveBuilder);

            var bufferSegStrList = curveSetBuilder.GetCurves();

            // short-circuit test
            if (bufferSegStrList.Count <= 0)
            {
                IGeometry emptyGeom = geomFact.CreateGeometryCollection(new IGeometry[0]);
                return(emptyGeom);
            }

            ComputeNodedEdges(bufferSegStrList, precisionModel);
            graph = new PlanarGraph(new OverlayNodeFactory());
            graph.AddEdges(edgeList.Edges);

            var subgraphList = CreateSubgraphs(graph);
            var polyBuilder  = new PolygonBuilder(geomFact);

            BuildSubgraphs(subgraphList, polyBuilder);
            var resultPolyList = polyBuilder.Polygons;

            var resultGeom = geomFact.BuildGeometry(resultPolyList);

            return(resultGeom);
        }
Пример #24
0
 /// <summary>
 /// Add a complete graph.
 /// The graph is assumed to contain one or more polygons,
 /// possibly with holes.
 /// </summary>
 /// <param name="graph"></param>
 public void Add(PlanarGraph graph)
 {
     Add(graph.EdgeEnds, graph.Nodes);
 }
Пример #25
0
 /// <summary>
 /// Add a complete graph.
 /// The graph is assumed to contain one or more polygons,
 /// possibly with holes.
 /// </summary>
 /// <param name="graph"></param>
 public virtual void Add(PlanarGraph graph)
 {
     Add(graph.EdgeEnds, graph.NodeValues);
 }
Пример #26
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:ConnectedSubgraphFinder"/> class.
 /// </summary>
 /// <param name="graph">The <see cref="PlanarGraph" />.</param>
 public ConnectedSubgraphFinder(PlanarGraph graph)
 {
     this.graph = graph;
 }
Пример #27
0
 // Use this for initialization
 void Start()
 {
     graph = GetComponent<PlanarGraph>();
     lastSelection = null;
 }
Пример #28
0
 /// <summary>
 /// Initializes a new instance of the <see cref="T:ConnectedSubgraphFinder"/> class.
 /// </summary>
 /// <param name="graph">The <see cref="PlanarGraph" />.</param>
 public ConnectedSubgraphFinder(PlanarGraph graph)
 {
     this.graph = graph;
 }
Пример #29
0
 /// <summary>
 /// Initializes a new instance of the BufferOp class.
 /// </summary>
 /// <param name="g0"></param>
 public BufferOp(Geometry g0) : base(g0)
 {
     _graph    = new PlanarGraph(new OverlayNodeFactory());
     _geomFact = new GeometryFactory(g0.PrecisionModel, g0.GetSRID());
 }
Пример #30
0
 public OverlayOp(Geometry g0, Geometry g1) : base(g0, g1)
 {
     _graph    = new PlanarGraph(new OverlayNodeFactory());
     _geomFact = new GeometryFactory(g0.PrecisionModel, g0.GetSRID());
 }         // public OverlayOp( Geometry g0, Geometry g1 ) : base( g0, g1 )
Пример #31
0
        internal static bool AnyIntersections(PlanarGraph <double> graph)
        {
            if (graph == null)
            {
                return(false);
            }
            SegmentGroup <double>        activeEdges = new SegmentGroup <double>();
            IEnumerator <Node <double> > points      = graph.GetEnumerator(); //walk through the points in xy sorted order

            Node <double> nd;
            LeakyResizableArray <Edge <double> > localEdges;

            int           localCt;
            int           activeCt = 0;
            Edge <double> localEdge;
            LineIntersectionResult <double> intersects;
            Point2 <double> localStart;
            Point2 <double> localEnd;
            Point2 <double> activeStart;
            Point2 <double> activeEnd;

            //new point event in the moving front
            while (points.MoveNext())
            {
                nd         = points.Current;
                localEdges = nd.Edges; //edges connected to this point

                localCt = (int)localEdges.Count;

                //compute intersections with other edges in the scan area
                for (int i = 0; i < localCt; i++)
                {
                    localEdge  = localEdges.Data[i];
                    localStart = localEdge.Start.Point;
                    localEnd   = localEdge.End.Point;
                    activeCt   = activeEdges.Edges.Count;

                    foreach (Edge <double> activeEdge in activeEdges)
                    {
                        if (object.ReferenceEquals(localEdge, activeEdge))
                        {
                            continue; //can't have a "full" match -- this is an exiting segment
                        }
                        activeStart = activeEdge.Start.Point;
                        activeEnd   = activeEdge.End.Point;

                        intersects = Coordinate2Utils.GetIntersection(localStart.X, localStart.Y, localEnd.X, localEnd.Y, activeStart.X, activeStart.Y, activeEnd.X, activeEnd.Y);
                        if (intersects.IntersectionType != LineIntersectionType.NoIntersection)
                        {
                            if (intersects.IntersectionType == LineIntersectionType.CollinearIntersection)
                            {
                                return(true); // there's a full segment of intersection
                            }
                            if (object.ReferenceEquals(localEdge.Previous, activeEdge) || object.ReferenceEquals(localEdge.Next, activeEdge))
                            {
                                continue; // this intersection is a single point at the common point of adjacent segments in a chain/ring
                            }
                            return(true);
                        }
                    }
                }
                //remove all exiting segments and add all starting segments
                //Action gets called exactly twice per edge -- once to add it, once to remove it
                for (int i = 0; i < localCt; i++)
                {
                    activeEdges.Action(localEdges.Data[i]);
                }
            }
            return(false);
        }
Пример #32
0
        public void Generate(int pointCount)
        {
            //Generate random points
            HashSet <Coordinate> hashSet = new HashSet <Coordinate>();
            {
                Random rand = new Random(seed);
                while (hashSet.Count < pointCount)
                {
                    double x = rand.NextDouble() * 2 - 1;
                    double y = rand.NextDouble() * 2 - 1;
                    if (x < -0.99 || y < -0.99 || x > 0.99 || y > 0.99)
                    {
                        continue;
                    }
                    hashSet.Add(new Coordinate(x, y));
                }
            }
            //Optimize points
            {
                Coordinate[] points = hashSet.ToArray();
                for (int i = 0; i < 2; i++)
                {
                    VoronoiDiagramBuilder builder = new VoronoiDiagramBuilder();
                    builder.SetSites(points);
                    VoronoiDiagram = builder.GetDiagram(new GeometryFactory());
                    for (int j = 0; j < points.Length; j++)
                    {
                        Polygon poly = VoronoiDiagram[j] as Polygon;
                        points[j] = new Coordinate(poly.Centroid.X, poly.Centroid.Y);
                    }
                }
            }
            //Build graph
            PlanarGraph graph;
            {
                VoronoiDiagram = ClipGeometryCollection(VoronoiDiagram, new Envelope(-1, 1, -1, 1));
                graph          = new PlanarGraph(new OverlayNodeFactory());
                List <Edge> edges = new List <Edge>();
                for (int i = 0; i < VoronoiDiagram.Count; i++)
                {
                    Polygon      poly   = VoronoiDiagram[i] as Polygon;
                    Coordinate[] coords = poly.Coordinates;
                    for (int j = 1; j < coords.Length; j++)
                    {
                        edges.Add(new Edge(new[] { coords[j - 1], coords[j] }, new Label(Location.Boundary)));
                    }
                }
                graph.AddEdges(edges);
            }
            //Convert graph
            Dictionary <Node, MapNode> nodeDict;

            {
                Dictionary <MapPolygon, HashSet <MapPolygon> > polys = new Dictionary <MapPolygon, HashSet <MapPolygon> >();
                nodeDict = new Dictionary <Node, MapNode>();
                Dictionary <MapNode, Tuple <HashSet <MapPolygon>, HashSet <MapEdge> > > dats =
                    new Dictionary <MapNode, Tuple <HashSet <MapPolygon>, HashSet <MapEdge> > >();
                for (int i = 0; i < VoronoiDiagram.Count; i++)
                {
                    List <MapNode> nodes = new List <MapNode>();
                    MapPolygon     poly  = new MapPolygon
                    {
                        CentroidX = VoronoiDiagram[i].Centroid.X,
                        CentroidY = VoronoiDiagram[i].Centroid.Y,
                        Polygon   = VoronoiDiagram[i] as Polygon
                    };
                    foreach (Coordinate j in VoronoiDiagram[i].Coordinates.Skip(1))
                    {
                        Node    n = graph.Find(j);
                        MapNode mapNode;
                        if (!nodeDict.TryGetValue(n, out mapNode))
                        {
                            mapNode = new MapNode {
                                X = j.X, Y = j.Y
                            };
                            dats[mapNode] =
                                new Tuple <HashSet <MapPolygon>, HashSet <MapEdge> >(new HashSet <MapPolygon> {
                                poly
                            },
                                                                                     new HashSet <MapEdge>());
                        }
                        else
                        {
                            dats[mapNode].Item1.Add(poly);
                        }
                        nodes.Add(nodeDict[n] = mapNode);
                    }
                    poly.Nodes = nodes.ToArray();
                    polys.Add(poly, new HashSet <MapPolygon>());
                }
                foreach (KeyValuePair <Node, MapNode> i in nodeDict)
                {
                    foreach (MapPolygon j in dats[i.Value].Item1)
                    {
                        foreach (MapPolygon k in dats[i.Value].Item1)
                        {
                            if (j != k)
                            {
                                polys[j].Add(k);
                                polys[k].Add(j);
                            }
                        }
                    }
                    foreach (EdgeEnd j in i.Key.Edges)
                    {
                        MapNode from = nodeDict[graph.Find(j.Coordinate)];
                        MapNode to   = nodeDict[graph.Find(j.DirectedCoordinate)];
                        dats[from].Item2.Add(new MapEdge {
                            From = from, To = to
                        });
                    }
                }
                int ftrh = dats.Count(_ => _.Value.Item2.Count == 0);
                foreach (KeyValuePair <MapNode, Tuple <HashSet <MapPolygon>, HashSet <MapEdge> > > i in dats)
                {
                    i.Key.Edges = i.Value.Item2.ToArray();
                }
                KeyValuePair <MapPolygon, HashSet <MapPolygon> >[] x = polys.ToArray();
                for (int i = 0; i < x.Length; i++)
                {
                    x[i].Key.Neighbour = x[i].Value.ToArray();
                    x[i].Key.Id        = i;
                }
                Polygons = x.Select(_ => _.Key).ToArray();
            }
            //Generate map
            DetermineLandmass();
            FindOceans();
            ComputeDistances();
            RedistributeElevation(nodeDict.Values);
            FindLakesAndCoasts();
        }
Пример #33
0
 //------------------------------------------------------------------------------------------------------------------
 void Start()
 {
     planarGraph = GameObject.FindGameObjectWithTag("GameController").GetComponent<PlanarGraph>();
     lineRenderer = GetComponent<LineRenderer>();
     isIntersect = false;
 }