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 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 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); }