Placing random points on map
#1 Members - Reputation: 287
Posted 20 February 2012 - 12:57 AM
I have generated a heightmap which will serve as terrain for my strategy game. Now I want to distribute points randomly on this map in order to create provinces. The game will use irregularly shaped regions as provinces (ie no rectangles or hexagons). I have an algorithm which given a set of points and a terrainmap (heightmap) divides areas into regions, but it's dependent on randomly distributed points. A problem is that I want much denser point clouds on land than on sea (as in 16-64 times more dense on land).
At the moment, I use some brute force algorithm to place a number of points on the map and make sure they are not too close. This is quite slow but gives really good results.
I was wondering if anyone has a better algorithm for this?
#4 Members - Reputation: 241
Posted 21 February 2012 - 07:17 AM
Depending on how you tweak it, you might end up with no points being closer than a certain distance. Or if you prefer, you could randomly decide whether to merge points, in order to allow points to occasionally be close together, but not often.
#5 Crossbones+ - Reputation: 1376
Posted 21 February 2012 - 12:27 PM
Then given the sizes of these two arrays, it is trivial to generate a random sampling of points from each that has whatever density is desired, where by density I mean the ratio num random points / num map points. If you need a more complicated definition of density i.e. one involving how close the points are together, then you need a more complicated algorithm. I, however, would at least try what I am suggesting: sometimes random number generators and probability will surprise you and you don't need to design in as much as you think you do.
If you do need strict bounds on how close the sampled points are together, I'd try a greedy approach: place a point then randomly place another point that is within the correct distance, then place another point that is within the correct distance, etc. Do this for the land and the sea separately. -- kind of like a randomized floodfill.
#6 Members - Reputation: 703
Posted 22 February 2012 - 07:15 AM
newPos = generateRandomPos()
if(newPos.isOnLand())
{
if(random() < 0.05)
return;
}
else
{
//on sea
if(random() > 0.05)
return;
}
acceptPos(newPos)
#7 Members - Reputation: 287
Posted 22 February 2012 - 07:57 AM
for(i = 0; i < NUM; i++)
{
numTriesLeft = 10000;
do
{
p = GetRandomPoint();
land = IsLand(p);
} while(--numTriesLeft > 0 && IsClosestPointCloserThan(p, (land ? 400 : 1600), pointlist))
if(numTriesLeft <= 0)
break;
AddPoint(pointlist, p);
}
I suppose it would be alot faster if I used an optimized IsClosestPointCloserThan() with grids or similar..
I have considered something similar to what jwezorek is suggesting, but it doesn't really help me apart from deciding how many land and how many sea provinces to place. It would pretty much require me to run the above algorithm twice, once for land and once for sea, but with p = GetRandomPointFromArray(land ? landArray : seaArray).
Here's an example of what I'm doing:
http://dvdmandt.net/grand/rev39/terrain.png - The heightmap
http://dvdmandt.net/grand/rev39/terrain_provinces.png - The heightmap with province results
http://dvdmandt.net/grand/rev39/world.png - Colored province results, also marks the points
#8 Crossbones+ - Reputation: 1376
Posted 22 February 2012 - 10:53 AM
1. Generate uniformly distributed points (without any special filtering based on distance from neighbors)
2. Create provinces
3. iterate through through provinces and extract pixel area of each via floodfill (or maybe you aleady have area from when they were generated)
4. If a province is too small in area union it on to a randomly selected neighbor. Repeat in a loop until it is big enough.
5. if a province is too big split in two (by selecting two internal points and computing the vornoi diagram or whatever you are using fro province generation)
This will also give you the possibility of ending up with some provinces that aren't convex which will be more realistic looking. In fact you could run the above on much more densely packed seed points then what you are using now, expecting to have to union together several seed provinces for each output province.
#9 Members - Reputation: 287
Posted 22 February 2012 - 11:04 AM
I suppose I should implement province merging/splitting, then I could try out your idea. But wouldn't it create very regularily placed points? If not, how do I place the points randomly and fairly equally distanced?
#10 Crossbones+ - Reputation: 1376
Posted 22 February 2012 - 11:29 AM
I already get provinces that aren't convex, the problem with your suggestion is that I want provinces to be fairly even-sized, and for water in particular, I want them to be fairly regular (except next to land). I've thought about splitting and merging provinces, in particular where there are provinces that are pretty much single pixels etc..
I suppose I should implement province merging/splitting, then I could try out your idea. But wouldn't it create very regularily placed points? If not, how do I place the points randomly and fairly equally distanced?
Why don't you do split-merge for land and for water either (a) just overlay an even triangular grid of points maybe, slightly perturbed, and generate water provinces from that or (b) run the same algorithm as for land but scale down the input mappoints first, generate seed points on scaled down map, scale up seed points, and generate provinces.
What are using for province generation? I thought the province maps were vornoi diagrams because I didn't look at full resolution, but now I see you have concave provinces in there.






