예제 #1
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();
 }
예제 #2
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();
        }
예제 #3
0
 static MapEdge SelectDownhill(MapNode node)
 {
     var dist = node.DistanceToCoast;
     MapEdge ret = node.Edges.First();
     foreach (var e in node.Edges)
         if (e.To.DistanceToCoast < dist)
             ret = e;
     return ret;
 }
예제 #4
0
        //void DetermineLandmass()    // Sine
        //{
        //    var rand = new Random(seed);
        //    int bumps = rand.Next(1, 7);
        //    double startAngle = rand.NextDouble() * 2 * Math.PI;
        //    double dipAngle = rand.NextDouble() * 2 * Math.PI;
        //    double dipWidth = rand.NextDouble() / 2 + 0.2;

        //    waters.Clear();
        //    foreach (var i in Polygons)
        //    {
        //        int total = 0;
        //        int water = 0;
        //        foreach (var j in i.Nodes)
        //        {
        //            var x = j.X;
        //            var y = j.Y;
        //            var angle = Math.Atan2(y, x);
        //            var length = 0.5 * (Math.Max(Math.Abs(x), Math.Abs(y)) + Math.Sqrt(x * x + y * y));

        //            var r1 = 0.5 + 0.40 * Math.Sin(startAngle + bumps * angle + Math.Cos((bumps + 3) * angle));
        //            var r2 = 0.7 - 0.20 * Math.Sin(startAngle + bumps * angle - Math.Sin((bumps + 2) * angle));
        //            if (Math.Abs(angle - dipAngle) < dipWidth ||
        //                Math.Abs(angle - dipAngle + 2 * Math.PI) < dipWidth ||
        //                Math.Abs(angle - dipAngle - 2 * Math.PI) < dipWidth)
        //                r1 = r2 = 0.2;

        //            if (!(length < r1 || (length > r1 * 0.5 && length < r2)))
        //            {
        //                j.IsWater = true;
        //                waters.Add(j);
        //                water++;
        //            }
        //            total++;
        //        }
        //    }
        //}

        void FindOceans()
        {
            oceans.Clear();
            foreach (var i in waters)
            {
                if (i.X == -1 || i.X == 1 ||
                    i.Y == -1 || i.Y == 1 ||
                    i.IsOcean ||
                    i.Edges.Select(_ => _.To).All(_ => _.IsWater))
                {
                    i.IsOcean = true;
                    continue;
                }

                bool            isOcean = false;
                Queue <MapNode> q       = new Queue <MapNode>();
                q.Enqueue(i);
                HashSet <MapNode> v = new HashSet <MapNode>();
                do
                {
                    MapNode current = q.Dequeue();
                    foreach (var j in current.Edges)
                    {
                        if (v.Contains(j.To) || !j.To.IsWater)
                        {
                            continue;
                        }
                        if (j.To.X == -1 || j.To.X == 1 ||
                            j.To.Y == -1 || j.To.Y == 1)
                        {
                            isOcean = true;
                            q.Clear();
                            break;
                        }
                        q.Enqueue(j.To);
                        v.Add(j.To);
                    }
                } while (q.Count > 0);
                if (isOcean)
                {
                    q.Clear();
                    v.Clear();
                    q.Enqueue(i);

                    do
                    {
                        MapNode current = q.Dequeue();
                        oceans.Add(current);
                        current.IsOcean = true;
                        foreach (var j in current.Edges)
                        {
                            if (v.Contains(j.To) || !j.To.IsWater)
                            {
                                continue;
                            }
                            q.Enqueue(j.To);
                            v.Add(j.To);
                        }
                    } while (q.Count > 0);
                }
            }
        }