示例#1
0
        string GetBiome(TerrainTile tile)
        {
            if (tile.PolygonId == -1)
            {
                return("unknown");
            }
            MapPolygon poly = map.Polygons[tile.PolygonId];

            if (beaches.Contains(poly))
            {
                return("beach");
            }
            else if (poly.IsWater)
            {
                if (poly.IsCoast)
                {
                    return("coast");
                }
                else if (poly.IsOcean)
                {
                    return("ocean");
                }
                else
                {
                    return("water");
                }
            }
            else
            {
                if (tile.Elevation >= elevationThreshold[3])
                {
                    if (tile.Moisture > moistureThreshold[4])
                    {
                        return("snowy");
                    }
                    else
                    {
                        return("mountain");
                    }
                }
                else if (tile.Elevation > elevationThreshold[2])
                {
                    if (tile.Moisture > moistureThreshold[4])
                    {
                        return("dryland");
                    }
                    else if (tile.Moisture > moistureThreshold[2])
                    {
                        return("taiga");
                    }
                    else
                    {
                        return("desert");
                    }
                }
                else if (tile.Elevation > elevationThreshold[1])
                {
                    if (tile.Moisture > moistureThreshold[4])
                    {
                        return("forest");
                    }
                    else if (tile.Moisture > moistureThreshold[2])
                    {
                        return("shrub");
                    }
                    else
                    {
                        return("desert");
                    }
                }
                else
                {
                    if (tile.Moisture > moistureThreshold[4])
                    {
                        return("rainforest");
                    }
                    else if (tile.Moisture > moistureThreshold[3])
                    {
                        return("forest");
                    }
                    else if (tile.Moisture > moistureThreshold[2])
                    {
                        return("grassland");
                    }
                    else
                    {
                        return("desert");
                    }
                }
            }
            return("unknown");
        }
示例#2
0
 public void Generate(int pointCount)
 {
     //Generate random points
     var hashSet = new HashSet<Coordinate>();
     {
         var 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
     {
         var points = hashSet.ToArray();
         for (var i = 0; i < 2; i++)
         {
             var builder = new VoronoiDiagramBuilder();
             builder.SetSites(points);
             VoronoiDiagram = builder.GetDiagram(new GeometryFactory());
             for (var j = 0; j < points.Length; j++)
             {
                 var 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 (var i = 0; i < VoronoiDiagram.Count; i++)
         {
             var poly = VoronoiDiagram[i] as Polygon;
             var coords = poly.Coordinates;
             for (var 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;
     {
         var polys = new Dictionary<MapPolygon, HashSet<MapPolygon>>();
         nodeDict = new Dictionary<Node, MapNode>();
         var dats = new Dictionary<MapNode, Tuple<HashSet<MapPolygon>, HashSet<MapEdge>>>();
         for (var i = 0; i < VoronoiDiagram.Count; i++)
         {
             var 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))
             {
                 var 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});
             }
         }
         var ftrh = dats.Count(_ => _.Value.Item2.Count == 0);
         foreach (var i in dats)
             i.Key.Edges = i.Value.Item2.ToArray();
         var x = polys.ToArray();
         for (var 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
        TerrainType GetBiomeTerrain(TerrainTile tile)
        {
            if (tile.PolygonId == -1)
            {
                return(TerrainType.None);
            }
            MapPolygon poly = map.Polygons[tile.PolygonId];

            if (!poly.IsWater && beaches.Contains(poly))
            {
                return(TerrainType.ShoreSand);
            }
            else if (poly.IsWater)
            {
                return(TerrainType.None);
            }
            else
            {
                if (tile.Elevation >= elevationThreshold[3])
                {
                    return(TerrainType.Mountains);
                }
                else if (tile.Elevation > elevationThreshold[2])
                {
                    if (tile.Moisture > moistureThreshold[4])
                    {
                        return(TerrainType.HighPlains);
                    }
                    else if (tile.Moisture > moistureThreshold[2])
                    {
                        return(TerrainType.HighForest);
                    }
                    else
                    {
                        return(TerrainType.HighSand);
                    }
                }
                else if (tile.Elevation > elevationThreshold[1])
                {
                    if (tile.Moisture > moistureThreshold[4])
                    {
                        return(TerrainType.MidForest);
                    }
                    else if (tile.Moisture > moistureThreshold[2])
                    {
                        return(TerrainType.MidPlains);
                    }
                    else
                    {
                        return(TerrainType.MidSand);
                    }
                }
                else
                {
                    if (poly.Neighbour.Any(_ => beaches.Contains(_)))
                    {
                        if (tile.Moisture > moistureThreshold[2])
                        {
                            return(TerrainType.ShorePlains);
                        }
                    }

                    if (tile.Moisture > moistureThreshold[3])
                    {
                        return(TerrainType.LowForest);
                    }
                    else if (tile.Moisture > moistureThreshold[2])
                    {
                        return(TerrainType.LowPlains);
                    }
                    else
                    {
                        return(TerrainType.LowSand);
                    }
                }
            }
            return(TerrainType.None);
        }
示例#4
0
        public IEnumerable <Coordinate[]> GenerateRoads()
        {
            double[] heights = map.Polygons
                               .Select(_ => _.DistanceToCoast.Value)
                               .Distinct()
                               .OrderBy(_ => _).ToArray();
            double[] roadHeights =
            {
                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 (MapPolygon i in map.Polygons)
            {
                if (i.IsOcean)
                {
                    queue.Enqueue(i);
                }
            }
            do
            {
                MapPolygon n = queue.Dequeue();
                foreach (MapPolygon 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 (MapPolygon i in map.Polygons)
            {
                foreach (MapNode 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 (MapEdge 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 (List <Coordinate> 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;
                            Coordinate 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 (Coordinate[] j in paths)
                {
                    if (j.Length < 4)
                    {
                        continue;
                    }
                    yield return(j);
                }
            }
        }
示例#5
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();
        }
示例#6
0
        private string GetBiome(TerrainTile tile)
        {
            if (tile.PolygonId == -1)
            {
                return("unknown");
            }
            if (tile.TileId == TileTypes.Road)
            {
                return("road");
            }
            if (tile.TileId == TileTypes.Water)
            {
                return("river");
            }
            MapPolygon poly = _map.Polygons[tile.PolygonId];

            if (tile.TileId == 0xb4)
            {
                return("towel");
            }

            if (_beaches.Contains(poly))
            {
                return("beach");
            }
            if (poly.IsWater)
            {
                if (poly.IsCoast)
                {
                    return("coast");
                }
                if (poly.IsOcean)
                {
                    return("ocean");
                }
                return("water");
            }
            if (tile.Elevation >= _elevationThreshold[3])
            {
                if (tile.Moisture > _moistureThreshold[4])
                {
                    return("snowy");
                }
                return("mountain");
            }
            if (tile.Elevation > _elevationThreshold[2])
            {
                if (tile.Moisture > _moistureThreshold[4])
                {
                    return("dryland");
                }
                if (tile.Moisture > _moistureThreshold[2])
                {
                    return("taiga");
                }
                return("desert");
            }
            if (tile.Elevation > _elevationThreshold[1])
            {
                if (tile.Moisture > _moistureThreshold[4])
                {
                    return("forest");
                }
                if (tile.Moisture > _moistureThreshold[2])
                {
                    return("shrub");
                }
                return("desert");
            }
            if (tile.Moisture > _moistureThreshold[4])
            {
                return("rainforest");
            }
            if (tile.Moisture > _moistureThreshold[3])
            {
                return("forest");
            }
            if (tile.Moisture > _moistureThreshold[2])
            {
                return("grassland");
            }
            return("desert");
            //return "unknown";
        }
示例#7
0
        private TerrainType GetBiomeTerrain(TerrainTile tile)
        {
            if (tile.PolygonId == -1 ||
                tile.TileId == TileTypes.Road ||
                tile.TileId == TileTypes.Water)
            {
                return(TerrainType.None);
            }
            MapPolygon poly = _map.Polygons[tile.PolygonId];

            if (!poly.IsWater && _beaches.Contains(poly))
            {
                return(TerrainType.ShoreSand);
            }
            if (poly.IsWater)
            {
                return(TerrainType.None);
            }
            if (tile.Elevation >= _elevationThreshold[3])
            {
                return(TerrainType.Mountains);
            }
            if (tile.Elevation > _elevationThreshold[2])
            {
                if (tile.Moisture > _moistureThreshold[4])
                {
                    return(TerrainType.HighPlains);
                }
                if (tile.Moisture > _moistureThreshold[2])
                {
                    return(TerrainType.HighForest);
                }
                return(TerrainType.HighSand);
            }
            if (tile.Elevation > _elevationThreshold[1])
            {
                if (tile.Moisture > _moistureThreshold[4])
                {
                    return(TerrainType.MidForest);
                }
                if (tile.Moisture > _moistureThreshold[2])
                {
                    return(TerrainType.MidPlains);
                }
                return(TerrainType.MidSand);
            }
            if (poly.Neighbour.Any(_ => _beaches.Contains(_)))
            {
                if (tile.Moisture > _moistureThreshold[2])
                {
                    return(TerrainType.ShorePlains);
                }
            }

            if (tile.Moisture > _moistureThreshold[3])
            {
                return(TerrainType.LowForest);
            }
            if (tile.Moisture > _moistureThreshold[2])
            {
                return(TerrainType.LowPlains);
            }
            return(TerrainType.LowSand);
            //return TerrainType.None;
        }