public void Build(IMap map, MapSettings settings) { foreach (var polygon in map.Polygons) { if (!polygon.IsInside && !polygon.IsOcean) { polygon.IsOcean = true; var queue = new Queue<Polygon>(); queue.Enqueue(polygon); while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var neighbor in current.Polygons.Where(neighbor => !neighbor.IsLand && !neighbor.IsOcean)) { neighbor.IsOcean = true; queue.Enqueue(neighbor); } } break; } } foreach (var corner in map.Corners) { corner.IsLand = corner.Polygons.Any(p => p.IsLand); corner.IsOcean = corner.Polygons.Any(p => p.IsOcean); } }
public IMap CreateMap(Structure structure, int seed, MapSettings settings) { var map = new Map(structure.Width, structure.Height); new FormPolygons(structure, new NoiseLineGenerator()).Build(map, settings); new CalculateDistanceFromEdgeBuilderComponent().Build(map, settings); new PerlinNoiseLandGenerator(seed, new PerlinNoiseGeneratorOld()).Build(map, settings); new DefineOcean().Build(map, settings); new AssignCoastBuilderComponent().Build(map, settings); new StructureLakes().Build(map, settings); new PerlinNoiseElevation(new PerlinNoiseGeneratorOld()).Build(map, settings); //new DistanceFromWaterElevation(new PerlinNoiseGenerator()).Build(map, settings); new AddRiversBuilderComponent(new CommonAddRiverStrategy()).Build(map, settings); new MoistureGenerator().Build(map, settings); new SetTerranTypeFromSite().Build(map, settings); return map; }
public void Build(IMap map, MapSettings settings) { var queue = new Queue<Polygon>(); foreach (var polygon in map.Polygons) { if (polygon.IsInside) { polygon.DistanceFromEdge = -1; } else { polygon.DistanceFromEdge = 0; queue.Enqueue(polygon); } } while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var polygon in current.Polygons) { if (polygon.DistanceFromEdge < 0) { polygon.DistanceFromEdge = current.DistanceFromEdge + 1; map.MaxDistanceFromEdge = Math.Max(map.MaxDistanceFromEdge, current.DistanceFromEdge + 1); queue.Enqueue(polygon); } } } }
public void Build(IMap map, MapSettings settings) { var noise = this.m_PerlinNoiseGenerator.GenerateNoise((int)map.Width, (int)map.Height, Seed, NoiseFrequency); var mapCenter = new Point2D(map.Width / 2, map.Height / 2); double l = 0; double r = 2; while (r - l > 1e-8) { double m = (l + r) / 2; int count = 0; foreach (var polygon in map.Polygons) { var center = polygon.Center; var dist = Geometry.SpecificDist(mapCenter, center, map.Width, map.Height); if (polygon.IsInside && map.ContainsPointInside(center)) { var noiseValue = noise[(int)center.X, (int)center.Y]; if (noiseValue > (this.BaseK + (dist > m ? (1 - this.BaseK) * (dist / m - 1) : 0))) { count++; } } } if (count > K * map.Polygons.Count) { r = m; } else { l = m; } } foreach (var polygon in map.Polygons) { var center = polygon.Center; var dist = Geometry.SpecificDist(mapCenter, center, map.Width, map.Height); if (polygon.IsInside && map.ContainsPointInside(center)) { var noiseValue = noise[(int)center.X, (int)center.Y]; /*polygon.IsLand = noise[(int) center.X, (int) center.Y] * (map.Width / (4 * dist + map.Width)) > 0.25;*/ polygon.IsLand = noiseValue > (this.BaseK + (dist > l ? (1 - this.BaseK) * (dist / l - 1) : 0)); } else { polygon.IsLand = false; } } }
public void Build(IMap map, MapSettings settings) { foreach (var corner in map.Corners.Where(c => c.IsLake)) { if (corner.Lake == null) { var lake = new Lake(); lake.Form(corner); } } }
public MapCreatorModel(double maxWidth, double maxHeight) { MaxWidth = maxWidth; MaxHeight = maxHeight; m_DefaultSettings = new MapSettings { LandPart = 0.4 }; CreateNewStructure(); }
public void Build(IMap map, MapSettings settings) { var noise = this.m_PerlinNoiseGenerator.GenerateNoise((int) map.Width, (int) map.Height, Seed, 8); CreateIndent(noise, map.Width, map.Height, m_Indent); double l = 0; double r = 1; while (r - l > 1e-8) { var m = (l + r)/2; int land = 0; int total = 0; foreach (var polygon in map.Polygons) { var center = polygon.Center; if (polygon.IsInside && map.ContainsPointInside(center)) { total++; var noiseValue = noise[(int) center.X, (int) center.Y]; if (noiseValue > m) { land++; } } } if (land > 0.4*total) { l = m; } else { r = m; } } foreach (var polygon in map.Polygons) { var center = polygon.Center; if (polygon.IsInside && map.ContainsPointInside(center)) { var noiseValue = noise[(int)center.X, (int)center.Y]; if (noiseValue > l) { polygon.IsLand = true; } } } }
public override void Build(IMap map, MapSettings settings) { if (map.Corners.Any(c => c.IsLand)) { var minStreamHeightForBigRivers = GetMinStreamHeight(map, this.BigRiversAreaPart); var minStreamHeightForRandomRivers = GetMinStreamHeight(map, this.SmallRiversAreaPart); List<Corner> riverSources = null; for (int k = 0; k < 500; k++) { List<Corner> newSources = new List<Corner>(); for (int i = 0; i < 20; i++) { newSources.Add(this.GetRandomLandCornerAboveTheHeight(map, minStreamHeightForBigRivers)); } for (int i = 0; i < 20; i++) { newSources.Add(this.GetRandomLandCornerAboveTheHeight(map, minStreamHeightForRandomRivers)); } if (riverSources == null || this.EstimateCorners(map, newSources) < this.EstimateCorners(map, riverSources)) { riverSources = newSources; } // TODO: maybe remove this strange thing foreach (var source in riverSources) { m_AddRiverStrategy.AddRiver(source, true); } } if (riverSources != null) { // TODO: set parameter? for (int k = 0; k < 20; k++) { foreach (var source in riverSources) { m_AddRiverStrategy.AddRiver(source, true); } } foreach (var source in riverSources) { m_AddRiverStrategy.AddRiver(source, false); } } } }
public void Build(IMap map, MapSettings settings) { var queue = new PriorityQueue<Corner>((a, b) => -a.DistanceForMoisture.CompareTo(b.DistanceForMoisture)); foreach (var corner in map.Corners) { if (corner.IsLake || corner.IsRiver/* || corner.IsOcean*/) { queue.Enqueue(corner); } corner.DistanceForMoisture = corner.IsWater ? 0 : this.m_MaxDist; } while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var corner in current.Corners) { // TODO: Chack how can it be if (corner != null) { // TODO: improve mechanic double k = corner.Elevation > current.Elevation ? 3 : 1; var newDist = current.DistanceForMoisture + Geometry.Dist(current, corner) * k; if (corner.DistanceForMoisture > newDist) { corner.DistanceForMoisture = newDist; queue.Enqueue(corner); } } } } SetAndNormalizeMoisture(map); foreach (var polygon in map.Polygons) { if (polygon.IsWater) { polygon.Moisture = 0; } else { polygon.Moisture = polygon.Corners.Average(c => c.Moisture); } } }
public IMap CreateMap(Structure structure, int seed, MapSettings settings) { var map = new Map(structure.Width, structure.Height); var report = new StringBuilder(); var stopwatch = new Stopwatch(); foreach (var component in m_ComponentsRegistry) { stopwatch.Reset(); stopwatch.Start(); component.Build(map, settings); stopwatch.Stop(); report.AppendLine(string.Format("{0}: {1} ms", component.GetType().Name, stopwatch.ElapsedMilliseconds)); } map.CreationReport = report.ToString(); return map; }
public void Build(IMap map, MapSettings settings) { foreach (var border in map.Borders) { if (border.Polygons[0].IsLand != border.Polygons[1].IsLand) { if (border.Polygons[0].IsOcean || border.Polygons[1].IsOcean) { border.IsOceanCoast = true; for (int i = 0; i < 2; i++) { border.Corners[i].IsOceanCoast = true; border.Polygons[i].IsOceanCoast = true; } } else { border.IsLakeCoast = true; for (int i = 0; i < 2; i++) { border.Corners[i].IsLakeCoast = true; border.Polygons[i].IsLakeCoast = true; } } } } // TODO: Strange dependancy with IsWater foreach (var corner in map.Corners) { if (corner.IsWater && !corner.IsOcean) { corner.IsLake = true; } } }
public void Build(IMap map, MapSettings settings) { var pointsDict = new Dictionary<StructurePoint, MapPoint>(); var trianglesDict = new Dictionary<Triangle, MapTriangle>(); var points = new List<MapPoint>(); foreach (var point in m_Structure.Points) { var mapPoint = new MapPoint(point); points.Add(mapPoint); var polygon = new Polygon(mapPoint); map.Polygons.Add(polygon); mapPoint.Polygon = polygon; pointsDict[point] = mapPoint; } var triangles = new List<MapTriangle>(); foreach (var triangle in m_Structure.Triangles) { var mapTriangle = new MapTriangle(triangle.Id); triangles.Add(mapTriangle); var corner = new Corner(triangle.Center); map.Corners.Add(corner); mapTriangle.Corner = corner; trianglesDict[triangle] = mapTriangle; } foreach (var triangle in m_Structure.Triangles) { var mapTriangle = trianglesDict[triangle]; for (int i = 0; i < 3; i++) { var point = triangle.Points[i]; if (point != null) { mapTriangle.Points[i] = pointsDict[point]; } var neighborTriangle = triangle.Triangles[i]; if (neighborTriangle != null) { mapTriangle.Triangles[i] = trianglesDict[neighborTriangle]; } } } foreach (var triangle in triangles) { for (int i = 0; i < 3; i++) { triangle.Corner.Polygons[i] = triangle.Points[i].Polygon; triangle.Points[i].Polygon.Corners.Add(triangle.Corner); } for (int i = 0; i < 3; i++) { var edge = triangle.Edge(i); var current = triangle.Triangles[i]; if (current != null) { triangle.Corner.Corners[i] = current.Corner; // TODO: Remove check if (triangle.Id == current.Id) { throw new InvalidDataException("Ids are equal"); } if (triangle.Id < current.Id) { var border = new Border(); border.Corners[0] = current.Corner; border.Corners[1] = triangle.Corner; border.Polygons[0] = edge.First.Polygon; border.Polygons[1] = edge.Second.Polygon; border.BasePolygon = edge.Second.Polygon; map.Borders.Add(border); triangle.Corner.Borders.Add(border); current.Corner.Borders.Add(border); edge.First.Polygon.Borders.Add(border); edge.Second.Polygon.Borders.Add(border); edge.First.Polygon.Polygons.Add(edge.Second.Polygon); edge.Second.Polygon.Polygons.Add(edge.First.Polygon); } } else { edge.First.Polygon.Polygons.Add(edge.Second.Polygon); edge.Second.Polygon.Polygons.Add(edge.First.Polygon); } } } foreach (Polygon polygon in map.Polygons) { Point2D center = polygon.Center; polygon.Corners.QuickSort((a, b) => Geometry.Vect(center, a, b).CompareTo(0)); polygon.Borders.QuickSort((a, b) => Geometry.Vect(center, a.Center, b.Center).CompareTo(0)); polygon.IsInside = polygon.Corners.All(map.ContainsPointInside); } foreach (var polygon in map.Polygons) { foreach (var border in polygon.Borders.Where(b => !b.BorderToDrawCreated)) { var borderPoints = m_NoiseLineGenerator.Generate(border.Corners[0], border.Polygons[0].BasePoint, border.Corners[1], border.Polygons[1].BasePoint, 2, true); /*var points = new List<Point2D> { border.Corners[0], border.Corners[1] };*/ /*border.Polygons[0].CornersToDraw.AddRange(points); border.Polygons[1].CornersToDraw.AddRange(points);*/ border.BorderToDraw = borderPoints; border.BorderToDrawCreated = true; } } foreach (var polygon in map.Polygons) { foreach (var border in polygon.Borders) { if (border.BasePolygon == polygon) { polygon.CornersToDraw.AddRange(border.BorderToDraw); } else { var borderPoints = new List<Point2D>(border.BorderToDraw); borderPoints.Reverse(); polygon.CornersToDraw.AddRange(borderPoints); } } } /*foreach (var polygon in map.Polygons) { var center = polygon.BasePoint; polygon.CornersToDraw.Sort((a, b) => Geometry.Vect(center, a, b).CompareTo(0)); }*/ }
public abstract void Build(IMap map, MapSettings settings);
public override void Build(IMap map, MapSettings settings) { // TODO: change parameters //var noise = new NormNoiseDecorator(m_NoiseGenerator).GenerateNoise((int)map.Width, (int)map.Height, new Random().Next(), 10); var noise = m_NoiseGenerator.GenerateNoise((int)map.Width, (int)map.Height, new Random().Next(), 10); var queue = new PriorityQueue<Corner>((a, b) => -a.DistanceFromCoast.CompareTo(b.DistanceFromCoast)); foreach (var corner in map.Corners) { if (corner.IsOceanCoast) { corner.DistanceFromCoast = 0; queue.Enqueue(corner); } else { corner.DistanceFromCoast = 1e9; } } while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var corner in current.Corners.Where(c => c != null)) { var dist = current.Dist(corner); if (corner.DistanceFromCoast > current.DistanceFromCoast + dist) { corner.DistanceFromCoast = current.DistanceFromCoast + dist; queue.Enqueue(corner); if (corner.IsLake) { double minNoise = noise[(int)corner.X, (int)corner.Y]; var lakeCorners = new List<Corner> { corner }; double bigStep = 2 * map.Corners.Count * this.SmallStep; var lakeQueue = new Queue<Corner>(); lakeQueue.Enqueue(corner); while (lakeQueue.Count > 0) { var lakeCorner = lakeQueue.Dequeue(); foreach (var c in lakeCorner.Corners) { if (c.IsLake && c.DistanceFromCoast > lakeCorner.DistanceFromCoast + bigStep) { c.DistanceFromCoast = lakeCorner.DistanceFromCoast + this.SmallStep * Geometry.Dist(lakeCorner, c) / map.Diagonal; lakeQueue.Enqueue(c); queue.Enqueue(c); minNoise = Math.Min(minNoise, noise[(int)c.X, (int)c.Y]); lakeCorners.Add(c); } } } foreach (var lakeCorner in lakeCorners) { noise[(int)lakeCorner.X, (int)lakeCorner.Y] = minNoise; } } } } } if (map.Corners.Any(c => c.IsLand)) { var maxDistance = map.Corners.Where(c => c.IsLand).Max(c => c.DistanceFromCoast); foreach (var corner in map.Corners) { double noiseInCorner; if (map.ContainsPointInside(corner)) { noiseInCorner = noise[(int) corner.X, (int) corner.Y]; } else { var point = new Point2D(corner); if (point.X < 0) { point.X = 0; } if (point.X >= map.Width - 1) { point.X = map.Width - 1; } if (point.Y < 0) { point.Y = 0; } if (point.Y >= map.Height - 1) { point.Y = map.Height - 1; } noiseInCorner = noise[(int) point.X, (int) point.Y]; } var distanceConstraint = 2 * corner.DistanceFromCoast/maxDistance; if (corner.IsOcean) { corner.Elevation = -Math.Min(distanceConstraint, noiseInCorner); } else { corner.Elevation = Math.Min(distanceConstraint, noiseInCorner); } } } this.NormalizeCornerElevation(map); }
public void Build(IMap map, MapSettings settings) { AddIslands(map); }
public override void Build(IMap map, MapSettings settings) { Comparison<Corner> comparison = (a, b) => -a.Elevation.CompareTo(b.Elevation); var queue = new PriorityQueue<Corner>(comparison); foreach (var corner in map.Corners) { if (!corner.IsOcean || corner.IsOceanCoast) { if (corner.IsOceanCoast) { corner.Elevation = 0; queue.Enqueue(corner); } else { corner.Elevation = 1e10; } } else { corner.Elevation = 0; } } /*while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var corner in current.Corners) { // TODO: check why can corner be null if (corner != null && corner.IsLand && corner.Elevation < 0) { corner.Elevation = current.Elevation + Geometry.Dist(current, corner) ; queue.Enqueue(corner); } } }*/ var noise = new NormNoiseDecorator(m_NoiseGenerator).GenerateNoise((int)map.Width, (int)map.Height, m_Random.Next(), 4); /*foreach (var corner in map.Corners) { if (corner.IsLand) { corner.Elevation = (corner.Elevation + 1) * noise[(int) corner.X, (int) corner.Y]; } } NormalizeElevation(map);*/ while (queue.Count > 0) { var current = queue.Dequeue(); foreach (var corner in current.Corners.Where(map.ContainsPointInside)) { var midPoint = (current + corner) / 2; var newDist = current.Elevation + Geometry.Dist(current, corner) * noise[(int)midPoint.X, (int)midPoint.Y]; if (corner.Elevation > newDist) { corner.Elevation = newDist; queue.Enqueue(corner); if (corner.IsLake) { double bigStep = 2 * map.Corners.Count * this.SmallStep; var lakeQueue = new Queue<Corner>(); lakeQueue.Enqueue(corner); while (lakeQueue.Count > 0) { var lakeCorner = lakeQueue.Dequeue(); foreach (var c in lakeCorner.Corners) { if (c.IsLake && c.Elevation > lakeCorner.Elevation + bigStep) { c.Elevation = lakeCorner.Elevation + this.SmallStep; lakeQueue.Enqueue(c); queue.Enqueue(c); } } } } } } } this.NormalizeCornerElevation(map); //TODO: obsolete? /*foreach (var polygon in map.Polygons) { polygon.Elevation = polygon.Corners.Average(p => p.Elevation); //polygon.Elevation = polygon.IsLand ? polygon.Corners.Average(p => p.Elevation) : 0; } */ }
public void Build(IMap map, MapSettings settings) { var moistures = map.Polygons.Where(p => p.IsLand).Select(p => p.DistanceForMoisture).OrderBy(p => p).ToArray(); var elevation = map.Polygons.Where(p => p.IsLand).Select(p => p.Elevation).OrderBy(p => p).ToArray(); int N = 6; int M = 4; double[] moistureLevels = new double[N]; double[] elevationLevels = new double[M]; if (moistures.Length > 0 && elevation.Length > 0) { for (int i = 0; i < N; i++) { moistureLevels[i] = (double)i / N; //moistures[(i * moistures.Length) / N]; } for (int i = 0; i < M; i++) { elevationLevels[i] = (double)i / M; //elevation[(i * elevation.Length) / M]; } foreach (var polygon in map.Polygons) { TerrainType terranType = TerrainType.Grassland; if (polygon.IsLand) { int ml = 0; for (int i = 0; i < N; i++) { if (polygon.Moisture > moistureLevels[i]) { ml = i; } } int el = 0; for (int i = 0; i < M; i++) { if (polygon.Elevation > elevationLevels[i]) { el = i; } } if (el == 0) { switch (ml) { case 0: terranType = TerrainType.SubtropicalDesert; break; case 1: terranType = TerrainType.Grassland; break; case 2: case 3: terranType = TerrainType.TropicalSeasonalForest; break; case 4: case 5: terranType = TerrainType.TropicalRainForest; break; } } if (el == 1) { switch (ml) { case 0: terranType = TerrainType.TemperatureDesert; break; case 1: case 2: terranType = TerrainType.Grassland; break; case 3: case 4: terranType = TerrainType.TemperatureDeciduousForest; break; case 5: terranType = TerrainType.TemperateRainForest; break; } } if (el == 2) { switch (ml) { case 0: case 1: terranType = TerrainType.TemperatureDesert; break; case 2: case 3: terranType = TerrainType.Shrubland; break; case 4: case 5: terranType = TerrainType.Taiga; break; } } if (el == 3) { switch (ml) { case 0: terranType = TerrainType.Scorched; break; case 1: terranType = TerrainType.Bare; break; case 2: terranType = TerrainType.Tundra; break; case 3: case 4: case 5: terranType = TerrainType.Snow; break; } } } else { if (polygon.IsLake) { terranType = TerrainType.Lake; } if (polygon.IsOcean) { // TODO: think about certan numbers if (polygon.Elevation > -0.2) { terranType = TerrainType.ShallowOcean; } else { terranType = TerrainType.DeepOcean; } } } polygon.Type = terranType; } } }