public IEnumerable <Coordinate[]> GenerateRoads()
        {
            var heights = map.Polygons
                          .Select(_ => _.DistanceToCoast.Value)
                          .Distinct()
                          .OrderBy(_ => _).ToArray();

            double[] roadHeights = new double[]
            {
                heights[heights.Length * 1 / 10],
                heights[heights.Length * 3 / 10],
                heights[heights.Length * 5 / 10],
                1
            };
            Dictionary <MapPolygon, int> centerContour = new Dictionary <MapPolygon, int>();
            Queue <MapPolygon>           queue         = new Queue <MapPolygon>();

            foreach (var i in map.Polygons)
            {
                if (i.IsOcean)
                {
                    queue.Enqueue(i);
                }
            }
            do
            {
                MapPolygon n = queue.Dequeue();
                foreach (var i in n.Neighbour)
                {
                    int newLevel;
                    if (!centerContour.TryGetValue(n, out newLevel))
                    {
                        newLevel = 0;
                    }

                    while (i.DistanceToCoast > roadHeights[newLevel])
                    {
                        newLevel++;
                    }

                    int iLevel;
                    if (!centerContour.TryGetValue(i, out iLevel))
                    {
                        iLevel = int.MaxValue;
                    }

                    if (newLevel < iLevel)
                    {
                        centerContour[i] = newLevel;
                        queue.Enqueue(i);
                    }
                }
            } while (queue.Count > 0);

            Dictionary <MapNode, int> cornerContour = new Dictionary <MapNode, int>();

            foreach (var i in map.Polygons)
            {
                foreach (var j in i.Nodes)
                {
                    int curr;
                    if (!cornerContour.TryGetValue(j, out curr))
                    {
                        curr = int.MaxValue;
                    }
                    int poly;
                    if (!centerContour.TryGetValue(i, out poly))
                    {
                        poly = int.MaxValue;
                    }
                    cornerContour[j] = Math.Min(curr, poly);
                }
            }

            List <Coordinate>[] points = new List <Coordinate> [roadHeights.Length - 1];
            for (int i = 0; i < points.Length; i++)
            {
                points[i] = new List <Coordinate>();
            }
            foreach (var i in map.Polygons.SelectMany(_ => _.Nodes).SelectMany(_ => _.Edges).Distinct())
            {
                if (cornerContour[i.From] < cornerContour[i.To])
                {
                    points[cornerContour[i.From]].Add(new Coordinate(
                                                          (i.From.X + i.To.X) / 2,
                                                          (i.From.Y + i.To.Y) / 2));
                }
            }
            foreach (var i in points)
            {
                List <Coordinate>   pts   = new List <Coordinate>();
                List <Coordinate[]> paths = new List <Coordinate[]>();
                for (int j = 0; j < i.Count; j++)
                {
                    double minDist = double.MaxValue;
                    for (int k = j + 1; k < i.Count; k++)
                    {
                        double dx = i[j].X - i[k].X;
                        double dy = i[j].Y - i[k].Y;
                        double d  = dx * dx + dy * dy;
                        if (d < minDist)
                        {
                            minDist = d;
                            var tmp = i[j + 1];
                            i[j + 1] = i[k];
                            i[k]     = tmp;
                        }
                    }
                    if (minDist > 0.1 && minDist != double.MaxValue)
                    {
                        if (pts.Count > 0)
                        {
                            pts.Add(pts[0]);
                        }
                        paths.Add(pts.ToArray());
                        pts.Clear();
                    }
                    else
                    {
                        pts.Add(i[j]);
                    }
                }
                if (pts.Count > 0)
                {
                    pts.Add(pts[0]);
                }
                paths.Add(pts.ToArray());
                pts.Clear();

                foreach (var j in paths)
                {
                    if (j.Length < 4)
                    {
                        continue;
                    }
                    yield return(j);
                }
            }
        }
 public void Generate(int pointCount)
 {
     //Generate random points
     HashSet<Coordinate> hashSet = new HashSet<Coordinate>();
     {
         Random rand = new Random(seed);
         while (hashSet.Count < pointCount)
         {
             var x = rand.NextDouble() * 2 - 1;
             var 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++)
         {
             var 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());
         var edges = new List<Edge>();
         for (int i = 0; i < VoronoiDiagram.Count; i++)
         {
             Polygon poly = VoronoiDiagram[i] as Polygon;
             var coords = poly.Coordinates;
             for (int j = 1; j < coords.Length; j++)
             {
                 edges.Add(new Edge(new Coordinate[] { 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>();
             var poly = new MapPolygon()
             {
                 CentroidX = VoronoiDiagram[i].Centroid.X,
                 CentroidY = VoronoiDiagram[i].Centroid.Y,
                 Polygon = VoronoiDiagram[i] as Polygon
             };
             foreach (var 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 (var i in nodeDict)
         {
             foreach (var j in dats[i.Value].Item1)
                 foreach (var k in dats[i.Value].Item1)
                     if (j != k)
                     {
                         polys[j].Add(k);
                         polys[k].Add(j);
                     }
             foreach (var j in i.Key.Edges)
             {
                 var from = nodeDict[graph.Find(j.Coordinate)];
                 var 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 (var i in dats)
             i.Key.Edges = i.Value.Item2.ToArray();
         var 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();
 }
Exemple #3
0
        public void Generate(int pointCount)
        {
            //Generate random points
            HashSet <Coordinate> hashSet = new HashSet <Coordinate>();
            {
                Random rand = new Random(seed);
                while (hashSet.Count < pointCount)
                {
                    var x = rand.NextDouble() * 2 - 1;
                    var 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++)
                {
                    var 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());
                var edges = new List <Edge>();
                for (int i = 0; i < VoronoiDiagram.Count; i++)
                {
                    Polygon poly   = VoronoiDiagram[i] as Polygon;
                    var     coords = poly.Coordinates;
                    for (int j = 1; j < coords.Length; j++)
                    {
                        edges.Add(new Edge(new Coordinate[] { 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>();
                    var            poly  = new MapPolygon()
                    {
                        CentroidX = VoronoiDiagram[i].Centroid.X,
                        CentroidY = VoronoiDiagram[i].Centroid.Y,
                        Polygon   = VoronoiDiagram[i] as Polygon
                    };
                    foreach (var 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 (var i in nodeDict)
                {
                    foreach (var j in dats[i.Value].Item1)
                    {
                        foreach (var k in dats[i.Value].Item1)
                        {
                            if (j != k)
                            {
                                polys[j].Add(k);
                                polys[k].Add(j);
                            }
                        }
                    }
                    foreach (var j in i.Key.Edges)
                    {
                        var from = nodeDict[graph.Find(j.Coordinate)];
                        var 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 (var i in dats)
                {
                    i.Key.Edges = i.Value.Item2.ToArray();
                }
                var 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();
        }