Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tadateruki/fastlem
A Rust library for simulating landscape evolution processes based on the Saleve model
https://github.com/tadateruki/fastlem
procedural-generation terrain-generation
Last synced: 19 days ago
JSON representation
A Rust library for simulating landscape evolution processes based on the Saleve model
- Host: GitHub
- URL: https://github.com/tadateruki/fastlem
- Owner: TadaTeruki
- License: mpl-2.0
- Created: 2023-08-25T01:27:37.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-09-16T03:48:58.000Z (2 months ago)
- Last Synced: 2024-09-16T05:16:41.177Z (2 months ago)
- Topics: procedural-generation, terrain-generation
- Language: Rust
- Homepage: https://fastlem.peruki.dev/
- Size: 2.13 MB
- Stars: 34
- Watchers: 1
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# fastlem
![terrain](sample.webp)
[![Crates.io](https://img.shields.io/crates/v/fastlem)](https://crates.io/crates/fastlem)
[![Documentation](https://docs.rs/fastlem/badge.svg)](https://docs.rs/fastlem)**fastlem** [/ˈfæstlɛm/] is a rust library that provides methods for simulating landscape evolution processes to create realistic terrain data with plausible relief.
Given a planar graph with topographic parameters assigned to each node, fastlem runs simulations and assigns elevations to the graph as output.
The **[fastlem web simulator](https://fastlem.peruki.dev/)** is available to try out manually creating virtual terrain with fastlem.
![fastlemweb2](https://github.com/TadaTeruki/fastlem/assets/69315285/1a98d63d-853d-4e76-bba5-b399f4772bf2)## Installation
> [!WARNING]
> This project is currently under development. During `0.1.*` the interface may change a lot.
>
> It is recommended to specify the version in detail.```
[dependencies]
fastlem = "0.1.4"
```## About the simulation
fastlem follows the **Salève** model[1], which is an analytical model for simulating landscape evolution in 2D. The algorithm for creating the drainage network follows the method of Guillaume Cordonnier, Jean Braun, Marie-Paule Cani, Bedrich Benes, Eric Galin, et al[2].
### Build a graph
Terrain data is represented as a planar graph. This graph structure is used to compute all topographic simulations for terrain generation.
For fastlem with 2D model, `TerrainModel2DBulider` is required to construct the graph from given sites as `TerrainModel2D` by computing a Delaunay triangulation. You can optionally use `relaxate_sites` to move the sites to approximately equal positions using Lloyd's algorithm.
```rust
let model = TerrainModel2DBulider::from_random_sites(num, bound_min, bound_max) // generate sites randomly
.relaxate_sites(1) // relaxate sites using Lloyd's algorithm
.unwrap()
.build() // build
.unwrap();
```### Create terrain generator
Before starting terrain generation, `TerrainGenerator` is required to use the planer graph and assign the topographic parameters to each site.
```rust
let terrain_generator = TerrainGenerator::default()
.set_model(model)
.set_parameters(
(0..num)
.map(|_| TopographicalParameters::default().set_erodibility(1.0))
.collect::<_>(),
);
```- **is_outlet** is whether the site can be an outlet (including oceans) or not. If `is_outlet`, the elevation is always set to 0.0.
- **erodibility** is the erodibility of the site. This is the main parameter that determines the shape of the terrain.### Generate terrain
```rust
let terrain = terrain_generator.generate().unwrap();
```Terrains are generated by calling `TerrainGenerator::generate()`.
### Get elevations
In general you can get the sites and elevations as vectors by calling `[Terrain]::sites()` and `[Terrain]::elevations()`.
The indices of each vector correspond to each other.
```rust
let sites = terrain.sites();
let elevations = terrain.elevations();
for i in 0..sites.len() {
println!(
"Site: ({}, {}), Elevation: {}",
sites[i].x, sites[i].y, elevations[i]
);
}
```You can also query the elevation of a specific site in the 2D surface model by calling `Terrain2D::get_elevation(Site2D)`.
```rust
let site = Site2D { x, y };
let elevation = terrain.get_elevation(&site);
```Note that this method uses natural neighbour interpolation (with the [naturalneighbor](https://crates.io/crates/naturalneighbor) package) to interpolate the specific elevation between sites and takes approximately O(logN).
Below is an example of using `get_elevation` to create an image of the generated terrain:
```rust
let img_width = 500;
let img_height = 500;let mut image_buf = image::RgbImage::new(img_width, img_height);
// calculate the max elevation
let max_elevation = terrain
.elevations()
.iter()
.fold(std::f64::MIN, |acc, &n| n.max(acc));for imgx in 0..img_width {
for imgy in 0..img_height {
let x = bound_max.x * (imgx as f64 / img_width as f64);
let y = bound_max.y * (imgy as f64 / img_height as f64);
let site = Site2D { x, y };
let elevation = terrain.get_elevation(&site);
if let Some(elevation) = elevation {
let color = ((elevation / max_elevation) * 255.0) as u8;
// put grayscale pixel
image_buf.put_pixel(imgx as u32, imgy as u32, image::Rgb([color, color, color]));
}
}
}image_buf.save("image.png").unwrap();
```### Reference
[1] Steer, P.: Short communication: Analytical models for 2D landscape evolution, Earth Surf. Dynam., 9, 1239–1250, https://doi.org/10.5194/esurf-9-1239-2021, 2021.
[2] Guillaume Cordonnier, Jean Braun, Marie-Paule Cani, Bedrich Benes, Eric Galin, et al.. Large Scale Terrain Generation from Tectonic Uplift and Fluvial Erosion. Computer Graphics Forum, 2016, Proc. EUROGRAPHICS 2016, 35 (2), pp.165-175. [⟨10.1111/cgf.12820⟩](https://dx.doi.org/10.1111/cgf.12820). [⟨hal-01262376⟩](https://inria.hal.science/hal-01262376)
## Contributing
Contributions are welcome.
Feel free to open an issue or pull request if you have any problems or suggestions.## Documentation
The [API reference](https://docs.rs/fastlem/latest/fastlem/) is available for this project.
The [examples](https://github.com/TadaTeruki/fastlem/tree/main/examples) are also useful. Reading the [landscape_evolution.rs](https://github.com/TadaTeruki/fastlem/blob/main/examples/landscape_evolution.rs) is recommended as a first step.
## License
MPL-2.0
## Preview of Examples
|**Simple Landscape Evolution**|**Simple Terrain Generation**|
|:---:|:---:|
|![Simple Landscape Evolution](images/out/landscape_evolution.png)|![Simple Terrain Generation](images/out/terrain_generation.png)|
|```$ cargo run --example landscape_evolution --release```|```$ cargo run --example terrain_generation --release```||**Advanced Terrain Generation**|**Terrain Generation from Given Parameters**|
|:---:|:---:|
|![Advanced Terrain Generation](images/out/terrain_generation_advanced.png)|![Terrain Generation from Given Parameters](images/out/sample_terrain.png)|
|```$ cargo run --example terrain_generation_advanced --release```|```$ cargo run --example sample_terrain --release```|