Exemplo n.º 1
0
        public void RunTest()
        {
            RandomHash random = new RandomHash();

            random.Next(5, 10, 1, 5, 24);
        }
        public static List <PoissonDisc> Sample2D(uint seed, double minRadius, Vector3D regionSize, int k = 4, bool createNeighbours = false, Vector3D centerPos = null, Func <Vector3D, float> calcRadius = null)
        {
            List <PoissonDisc> points    = new List <PoissonDisc>();
            double             maxRadius = 0f;
            int searchZone = 2;

            RandomHash hash     = new RandomHash(seed);
            double     cellSize = minRadius * 2 / 1.41421356237; // Minimum distance between cells divided by sqrt(2)

            int[,] grid = new int[(int)Math.Ceiling(regionSize.X / cellSize), (int)Math.Ceiling(regionSize.Y / cellSize)];
            List <PoissonDisc> spawnPoints = new List <PoissonDisc>
            {
                new PoissonDisc(centerPos ?? regionSize / 2, minRadius)
            };

            points.Add(spawnPoints[0]);
            grid[(int)(spawnPoints[0].position.X / cellSize), (int)(spawnPoints[0].position.Y / cellSize)] = points.Count;

            int currVal = 0;

            while (spawnPoints.Count > 0)
            {
                int         spawnIndex  = hash.Next(0, spawnPoints.Count, ++currVal);
                PoissonDisc spawnCentre = spawnPoints[spawnIndex];

                bool   candidateAccepted = false;
                double randRot           = hash.NextDouble(0, 1, currVal);
                double nextRadius        = calcRadius == null ? minRadius : calcRadius(spawnCentre.position);
                double distance          = spawnCentre.radius + nextRadius;
                double r = distance + 0.0000001;

                for (int j = 0; j < k; j++)
                {
                    double theta = pi * (randRot + 1.0 * j / k);

                    double x = spawnCentre.position.X + r * Math.Cos(theta);
                    double y = spawnCentre.position.Y + r * Math.Sin(theta);

                    Vector3D candidate = new Vector3D(x, y, 0);
                    if (IsValid2D(candidate, nextRadius, searchZone, regionSize, cellSize, grid, points))
                    {
                        if (distance > maxRadius)
                        {
                            maxRadius  = distance;
                            searchZone = (int)Math.Ceiling(distance / cellSize);
                        }
                        PoissonDisc disc = new PoissonDisc(candidate, nextRadius);
                        points.Add(disc);
                        spawnPoints.Add(disc);
                        grid[(int)(candidate.X / cellSize), (int)(candidate.Y / cellSize)] = points.Count;
                        candidateAccepted = true;
                        break;
                    }
                }
                if (!candidateAccepted)
                {
                    spawnPoints.RemoveAt(spawnIndex);
                }
            }

            if (createNeighbours)
            {
                return(CreateNeighbourList2D(points, grid, searchZone));
            }

            return(points);
        }