generate 2d poisson sampling for any point in csharp

Poisson Disk Sampling is a popular algorithm used in computer graphics to generate evenly spaced and non-random points. It is useful in a variety of applications, such as generating realistic textures and landscapes, or even in generating virtual scenarios for video games.

To generate 2D Poisson Sampling in C#, we can use the algorithm described in this article: https://www.jasondavies.com/poisson-disc/

main.cs
public static List<Vector2> GeneratePoissonSampling(float radius, int numSamples, int numAttemptsPerSample)
{
    List<Vector2> points = new List<Vector2>();
    Vector2[,] grid = new Vector2[100, 100];
    List<Vector2> activeList = new List<Vector2>();

    Random random = new Random();

    // Generate first point randomly
    Vector2 firstPoint = new Vector2(random.Next(0, 100), random.Next(0, 100));
    activeList.Add(firstPoint);
    points.Add(firstPoint);
    grid[(int)firstPoint.X, (int)firstPoint.Y] = firstPoint;

    while(activeList.Count > 0 && points.Count < numSamples)
    {
        int activeIndex = random.Next(0, activeList.Count);
        Vector2 currentPoint = activeList[activeIndex];

        // Try to generate new samples around the current point
        bool found = false;
        for(int i = 0; i < numAttemptsPerSample; i++)
        {
            float angle = (float)random.NextDouble() * 2f * Mathf.PI;
            float distance = (float)random.NextDouble() * radius + radius;

            Vector2 newPoint = currentPoint + new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * distance;

            // Check if the new sample is within the bounds of the grid and does not intersect any of the existing points
            if(newPoint.X >= 0 && newPoint.X < 100 && newPoint.Y >= 0 && newPoint.Y < 100)
            {
                bool valid = true;
                int startX = Mathf.Max((int)(newPoint.X - radius), 0);
                int endX = Mathf.Min((int)(newPoint.X + radius), 99);
                int startY = Mathf.Max((int)(newPoint.Y - radius), 0);
                int endY = Mathf.Min((int)(newPoint.Y + radius), 99);

                for(int x = startX; x <= endX; x++)
                {
                    for(int y = startY; y <= endY; y++)
                    {
                        if(grid[x, y] != null && Vector2.Distance(grid[x, y], newPoint) < radius)
                        {
                            valid = false;
                            break;
                        }
                    }

                    if(!valid)
                    {
                        break;
                    }
                }

                if(valid)
                {
                    activeList.Add(newPoint);
                    points.Add(newPoint);
                    grid[(int)newPoint.X, (int)newPoint.Y] = newPoint;

                    found = true;
                    break;
                }
            }
        }

        if(!found)
        {
            activeList.RemoveAt(activeIndex);
        }
    }

    return points;
}
2613 chars
75 lines

This code generates Poisson Sampling by selecting a random point from the active list, generating several new samples around it, and checking if each of these new samples is valid (i.e., not too close to any of the existing points). If a new sample is valid, it is added to the active list and the points list. If no new valid samples are found, the current point is removed from the active list. The process continues until we have generated the desired number of points.

You can use this function to generate Poisson Sampling for any point in your C# application.

gistlibby LogSnag