I am trying to come up with a method for generating X amount of random points in a given area (in my case a square). The one thing that makes this such an issue is that each point has to be at least Y units away from all other points.
What springs to mind at first is (in c#) to check the distance between the new point and all existing points:
while(points.Count < pointsToGenerate)
{
Point newPoint = NewPoint();
bool addPoint = true;
foreach(Point p in points)
{
if((p - newPoint).Length() < minDistance)
{
addPoint = false;
break;
}
}
if(addPoint)
{
points.Add(newPoint);
}
}
Now this would certainly work however if no valid points were ever found this would become a never ending loop. So throw in a magical number Z there as a limit of tries?
if(loopCount > 100)
{
break;
}
Now this has some obvious problems. If the points are randomly generated, then loopCount can go above Z even if there are places left to place the point. It not only can, but it will happen!
What I could do is to create a list of available point per each pass and then select a random one of those. This would work flawlessly except for one thing: Performance. I’m not in need of super performance in my application, but the area is 1000^2. A lot of points to check per pass even if I limit myself to integers!
So, what I can come up with might not suffice, thus I would love some assistance on this. Is there a better way to generate X points in an area A with the minimum distance between points Y?
Thanks!
EDIT: With better, I mean generally better where a balance of performance vs perfection is achieved. A bit vague, I know. I’m not entierly sure how much overhead I can have for generating those points yet so I’m basically after anything more elegant than my own method.
~Robert
To understand your problem : are you looking for the optimal answer (i.e : homework), or for a very good algorithm that’s better than creating random points?
In the first case, I’m afraid it’s a very complicated problem if you’ve got no prior information on the area A. And I believe that it’ll be hard to find an algorithm that’s faster than exploring every single case.
However, if you’ve got some prior information on A then things might be simpler. For example, if it’s convex, you can exploit the fact that the optimal pavement if your space is infinite is hexagonal. It means that you have to put your points (in X) at the extremities of the triangles
So :
This algorithm is not optimal (not unless you define a very good “favoring the ones on the convex hull”…)
Edit : Mr E’s comment reminded me that the optimal pavement thing derives from circle packing. Kudos to him for the precision!
However, I do have another algorithm that looks very nice, and is perhaps even optimal! It does not require any conditions on A, and is a bit expensive, but not too much. Yeah, I know, it contradicts what I said, but who cares! Having a good algorithm is nice enough.
Let’s name B the set of the available points so far. And C the points that form the extremities of B. At the beginning, B=A, and if A is a square, then C consists of 4 points (the corners). You simply have to recursively :
I know that if you work in a 1000×1000 grid, C begins with 4 points, but after adding one point to X, it means that C grows to 1570 points (roughly (pi/2)1000).
You have to notice that you never put in memory B, which is big (O(n^2) if A can be put in a nn grid) Only C, and I believe that at any point, the size of C is O(n) , which remains much better than O(n^2). And computing the diameter remains O(size(C)) = O(n)