Пример #1
0
        public static List <VoronoiSite> Create(int width, int height, int pointCount, int relaxations, int seed)
        {
            RandomGenerator.ResetSeed(seed);
            Dictionary <Vector, VoronoiSite> points = new Dictionary <Vector, VoronoiSite>(pointCount);

            for (int i = 0; i < pointCount; i++)
            {
                Vector point = new Vector(RandomGenerator.Get(0, width), RandomGenerator.Get(0, height));
                try
                {
                    points.Add(point, new VoronoiSite(point));
                }
                catch (ArgumentException) // In case two points are to close one from each other
                {
                    i--;
                }
            }
            List <VoronoiSite> sites = CalculateVoronoiGraph(points, width, height);

            for (int i = 0; i < relaxations; i++)
            {
                Dictionary <Vector, VoronoiSite> newPoints = new Dictionary <Vector, VoronoiSite>();
                foreach (VoronoiSite site in sites)
                {
                    Vector newPoint = new Vector(site.VoronoiPoints.Average(p => p[0]),
                                                 site.VoronoiPoints.Average(p => p[1]));
                    newPoints.Add(newPoint, new VoronoiSite(newPoint));
                }
                points = newPoints;
                sites  = CalculateVoronoiGraph(points, width, height);
            }
            //Create water
            IWaterGenerator waterGenerator = new FloodFillWaterGenerator();

            //waterGenerator = new PerlinWaterGenerator();
            waterGenerator.GenerateWater(sites);
            //Associate water distance from shore and split the water in cluster (independant seas)
            while (true)
            {
                Stack <VoronoiSite> toBeProcessedSites = new Stack <VoronoiSite>();
                VoronoiSite         site = sites.FirstOrDefault(s => s.ShoreDistance == VoronoiSite.DefaultShoreDistance && s.Neighbourgs.Any(p => p.IsWater != s.IsWater));
                if (site == null)
                {
                    break;
                }
                site.ShoreDistance = 1;
                toBeProcessedSites.Push(site);
                Cluster cluster = new Cluster();
                while (toBeProcessedSites.Count > 0)
                {
                    VoronoiSite item = toBeProcessedSites.Pop();
                    item.Cluster = cluster;
                    if (item.Neighbourgs.Any(s => item.IsWater != s.IsWater))
                    {
                        item.ShoreDistance = 1;
                    }
                    foreach (VoronoiSite neighbourg in item.Neighbourgs)
                    {
                        if ((neighbourg.IsWater == item.IsWater) && neighbourg.ShoreDistance > item.ShoreDistance + 1)
                        {
                            neighbourg.ShoreDistance = item.ShoreDistance + 1;
                            if (!toBeProcessedSites.Contains(neighbourg))
                            {
                                toBeProcessedSites.Push(neighbourg);
                            }
                        }
                    }
                }
            }
            DebugConsole.WriteLine("Land tiles  : " + sites.Count(s => !s.IsWater) + " (" + string.Format("{0:P}", (float)sites.Count(s => !s.IsWater) / sites.Count) + ")");
            DebugConsole.WriteLine("Water tiles : " + sites.Count(s => s.IsWater) + " (" + string.Format("{0:P}", (float)sites.Count(s => s.IsWater) / sites.Count) + ")");
            return(sites);
        }
Пример #2
0
 public static List<VoronoiSite> Create(int width, int height, int pointCount, int relaxations, int seed)
 {
     RandomGenerator.ResetSeed(seed);
     Dictionary<Vector, VoronoiSite> points = new Dictionary<Vector, VoronoiSite>(pointCount);
     for (int i = 0; i < pointCount; i++)
     {
         Vector point = new Vector(RandomGenerator.Get(0, width), RandomGenerator.Get(0, height));
         try
         {
             points.Add(point, new VoronoiSite(point));
         }
         catch (ArgumentException) // In case two points are to close one from each other
         {
             i--;
         }
     }
     List<VoronoiSite> sites = CalculateVoronoiGraph(points, width, height);
     for (int i = 0; i < relaxations; i++)
     {
         Dictionary<Vector, VoronoiSite> newPoints = new Dictionary<Vector, VoronoiSite>();
         foreach (VoronoiSite site in sites)
         {
             Vector newPoint = new Vector(site.VoronoiPoints.Average(p => p[0]),
                site.VoronoiPoints.Average(p => p[1]));
             newPoints.Add(newPoint, new VoronoiSite(newPoint));
         }
         points = newPoints;
         sites = CalculateVoronoiGraph(points, width, height);
     }
     //Create water
     IWaterGenerator waterGenerator = new FloodFillWaterGenerator();
     //waterGenerator = new PerlinWaterGenerator();
     waterGenerator.GenerateWater(sites);
     //Associate water distance from shore and split the water in cluster (independant seas)
     while (true)
     {
         Stack<VoronoiSite> toBeProcessedSites = new Stack<VoronoiSite>();
         VoronoiSite site = sites.FirstOrDefault(s => s.ShoreDistance == VoronoiSite.DefaultShoreDistance && s.Neighbourgs.Any(p => p.IsWater != s.IsWater));
         if (site == null)
             break;
         site.ShoreDistance = 1;
         toBeProcessedSites.Push(site);
         Cluster cluster = new Cluster();
         while (toBeProcessedSites.Count > 0)
         {
             VoronoiSite item = toBeProcessedSites.Pop();
             item.Cluster = cluster;
             if (item.Neighbourgs.Any(s => item.IsWater != s.IsWater)) item.ShoreDistance = 1;
             foreach (VoronoiSite neighbourg in item.Neighbourgs)
             {
                 if ((neighbourg.IsWater == item.IsWater) && neighbourg.ShoreDistance > item.ShoreDistance + 1)
                 {
                     neighbourg.ShoreDistance = item.ShoreDistance + 1;
                     if (!toBeProcessedSites.Contains(neighbourg))
                         toBeProcessedSites.Push(neighbourg);
                 }
             }
         }
     }
     DebugConsole.WriteLine("Land tiles  : " + sites.Count(s => !s.IsWater) +" ("+ string.Format("{0:P}", (float)sites.Count(s => !s.IsWater) / sites.Count)+")");
     DebugConsole.WriteLine("Water tiles : " + sites.Count(s => s.IsWater) + " (" + string.Format("{0:P}", (float)sites.Count(s => s.IsWater) / sites.Count)+")");
     return sites;
 }