Exemple #1
0
        private static List <VoronoiSite> CalculateVoronoiGraph(Dictionary <Vector, VoronoiSite> points, int width, int height)
        {
            VoronoiGraph result = Fortune.ComputeVoronoiGraph(points.Keys.ToList());

            foreach (VoronoiEdge edge in result.Edges)
            {
                VoronoiSite a = points[edge.LeftData];
                VoronoiSite b = points[edge.RightData];
                a.Neighbourgs.Add(b);
                b.Neighbourgs.Add(a);
                a.Edges.Add(edge);
                b.Edges.Add(edge);
            }
            foreach (VoronoiSite site in points.Values)
            {
                site.Reorder(width, height);
            }
            return(points.Values.ToList());
        }
Exemple #2
0
        public void GenerateWater(List <VoronoiSite> sites)
        {
            NoiseGenerator.Frequency = 0.0005;
            foreach (VoronoiSite site in sites)
            {
                if ((site.IsOnBorder && RandomGenerator.GetDouble(0, 1) < 0.60) || (NoiseGenerator.Noise((int)site.VoronoiCenter[0], (int)site.VoronoiCenter[1]) + 1) * 127 < 125)
                {
                    site.IsWater = true;
                }
            }
            Stack <VoronoiSite> processingStack = new Stack <VoronoiSite>(sites.Where(s => s.IsWater));

            while (processingStack.Count > 0)
            {
                VoronoiSite site = processingStack.Pop();
                if (!site.IsOnBorder && RandomGenerator.GetDouble(0, 1) < 0.50)
                {
                    continue;
                }
                double threshold = site.IsOnBorder ? RandomGenerator.GetDouble(0, 0.85) : RandomGenerator.GetDouble(0, 0.67);
                foreach (VoronoiSite target in site.Neighbourgs)
                {
                    if (target.IsWater)
                    {
                        continue;
                    }
                    if (RandomGenerator.GetDouble(0, 1) < threshold)
                    {
                        target.IsWater = true;
                        if (!processingStack.Contains(target))
                        {
                            processingStack.Push(target);
                        }
                    }
                }
            }
            //Remove single cell islands
            foreach (VoronoiSite island in sites.Where(p => !p.IsWater && p.Neighbourgs.All(i => i.IsWater)))
            {
                island.IsWater = true;
            }
        }
Exemple #3
0
        public void GenerateWater(List <VoronoiSite> sites)
        {
            Stack <VoronoiSite> processingStack = new Stack <VoronoiSite>();

            foreach (VoronoiSite site in sites)
            {
                if (site.IsOnBorder || RandomGenerator.GetDouble(0, 80) < 1)
                {
                    site.IsWater = true;
                    processingStack.Push(site);
                }
            }
            while (processingStack.Count > 0)
            {
                if (RandomGenerator.GetDouble(0, 1) < 0.60)
                {
                    continue;
                }
                VoronoiSite site      = processingStack.Pop();
                double      threshold = RandomGenerator.GetDouble(0, 0.65);
                foreach (VoronoiSite target in site.Neighbourgs)
                {
                    if (target.IsWater)
                    {
                        continue;
                    }
                    if (RandomGenerator.GetDouble(0, 1) < threshold)
                    {
                        target.IsWater = true;
                        if (!processingStack.Contains(target))
                        {
                            processingStack.Push(target);
                        }
                    }
                }
            }
            //Remove single cell islands
            foreach (VoronoiSite island in sites.Where(p => !p.IsWater && p.Neighbourgs.All(i => i.IsWater)))
            {
                island.IsWater = true;
            }
        }
Exemple #4
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);
        }