I rewrote the drainage basin algorithm and fixed many problems that were in the previous version. The main problems that were fixed or mitigated are :
- Proper result data generated to create elevation from
- Proper result data generated to create rivers from
- Faster performance
- No more long drainage basins that run parallel to the coast line
- Major refactoring of drainage basin code, since it now basically works how I want it needs to be properly organized. Currently the drainage basin creation, river running, and elevation creation are all happening together in one class. Each step needs to be separated so that they can be controlled independently.
- Still need to deal with creating bodies of water inland.
- Tweak/Change river running algorithm. The current one gets the job done but it could look better.
- Not sure if I like the elevation being generated yet. Need to play with it more.
- Should work on a better color palette for rendering elevation.
To be able to create drainage basins in the manner described in my previous post I need to be able to traverse the coast of an island in order as a path. I already have code to extract a coastline from a map but it is simply a brute force match which processes the entire map. To solve this problem I implemented a marching squares algorithm. To test it I plotted the paths it generated with increasing intensity to see that the points are in order.
To deal with endorheic basins I have eliminated the ones that were formed in the continent mask. Instead I am planning to add them in after the basins have been created by randomly selecting certain basins and have them drain inland instead. After the coast is closed that basin can be processed in the same way as an island but inverted. Also the drainage basin code needs to be tweaked. Instead of choosing the next point by selecting the one farthest from the current divide it may be better to pre-select points with a more even distribution on the coast and then connect the farthest in this set. This should eliminate the wide basins that are difficult to place river networks on. Hopefully I can test this later this week. For now here is a set of continents with drainage basins with the interior water removed.
The following images are examples of randomly generated drainage basins. The plan is to use these to develop elevation ranges as well as plot rivers. Here is a description of the steps used in the algorithm:
- Create a land/ocean mask using the process described earlier.
- For each island in the map do the following:
- Randomly choose a point on the outside coast.
- Choose a point by selecting the coastal point that is furthest away from the random point. This will be the first start point.
- Choose a point by selecting the coastal point that is furthest away from the start point. This will be the end point.
- Generate a RidgedMultifractal noise map and process it as follows: Invert, Absolute Value, Normalize from 1.0 – 25.0, Exponentiate by 5.0.
- Find the path from start point to end point by using Dijkstra’s algorithm with the RidgedMultifractal pattern providing the traversal costs.
- Create a collection to store all drainage boundary points in and add all points in the path to it. This collection will be referred to as “allPoints”.
- Repeat the following steps based on the size of the current island:
- Find the coastal point whose nearest neighbor in allPoints is the furthest distance away. This will be the start point.
- Find the nearest point in allPoints from the start point. This will be the end point.
- Using Dijkstra’s algorithm and the previously defined noise pattern find the path from the start point to the end point.
- Add this path to allPoints and repeat.
- Using allPoints and the original land/ocean mask uniquely identify each drainage basin.
The next step will be figure out how to create endorheic basins for large bodies of water that are inside an island.
My current goal is to generate mountain ranges that are interesting and do not always end up in the middle of the land mass which seems to happen in many world generators I have seen. The mountains in the center of the land mass works nicely for islands but does not make much sense for continents. The results of this first experiment are not very good but I will describe the process anyways.
- Generate a voronoi diagram (A) based off of 32 randomly selected points.
- Make the voronoi diagram (A) “noisy”.
- Select all points that are on the border of a segment.
- Use the selected points to create another voronoi diagram (B) based where each cell has a value equal to the distance to the nearest border point.
- Generate 2 FBM noise patterns (C) and (D).
- Process voronoi diagram (B) as follows: add 1 to every value, exponentiate every value by 0.3, add (C), invert, normalize, max of (B) and 0.25, multiply by (D).
- Use the process in the previous post to generate a continent mask (E).
- Add (B) and (E) then multiply by (E)
Added Continent Samples.
Steps to create:
- Outline the border to ensure all edges are ocean.
- Draw random lines originating from each edge to avoid flat coast lines.
- Draw random lines in the interior to separate landforms and create large bodies of water.
- Build Voronoi Diagram based on points that are members of lines. (Each cell value equals the distance to the nearest line point)
- Normalize Voronoi Diagram to values between 0.0 and 1.0
- Create FBM noise pattern and normalize to 0.0 and 1.0.
- Multiply Voronoi Diagram by FBM noise pattern.
- Set values < 0.2 to ocean, >= 0.2 to land.
Added Distortion Noise Samples. Each distortion noise function combines two noise functions, the second function is used to distort the coordinates before being put into the first function.
Added Basic Noise Samples. These two noise functions serve as the basis for all other noise functions.
Added Particle Deposition Samples.
Added Fault Line Samples.