using System; using System.Linq; using Assets.Common; using Assets.PointDistribution; namespace Assets.AnnotationPass { public class ForestPass : IAnnotationPass { public const string TreesProperty = "Trees"; public double TreeRadius { get; set; } = 2; public double ForestRatio { get; set; } = .4; public double Scale { get; set; } = .01; public double Lacunarity { get; set; } = 1.7; public double Dampening { get; set; } = .7; public void Annotate(Map map) { var random = new Random(map.Seed + 2137); var sampler = new PoissonDiskSampler(TreeRadius) { Generator = random }; var perlin = new PerlinNoiseGenerator { Iterations = 4, Scale = (float)Scale, Lacunarity = (float)Lacunarity, Decay = (float)Dampening, Offset = new Point(random.NextDouble() * 150, random.NextDouble() * 150) }; var points = sampler .Generate(map.Size.Width, map.Size.Height) .Where(p => perlin.GetValue(p) < ForestRatio) .Select(p => new Tree { Placement = p, Site = map.Sites.Vertices.FirstOrDefault(site => PointUtils.IsPointInside(p, site.Boundary.Select(n => map.Boundaries[n]))) }) .Where(t => t.Site != null) .Where(t => t.Site.Tags.Contains(CommonTags.Land) && t.Site.Tags.Contains(CommonTags.Empty)) ; map.SetProperty(TreesProperty, points.ToList()); } } }