4个版本
0.1.4 | 2024年1月26日 |
---|---|
0.1.3 | 2024年1月24日 |
0.1.2 | 2023年12月6日 |
0.1.0 | 2023年11月10日 |
#234 in 算法
1MB
911 行
fastlem
fastlem [/ˈfæstlɛm/] 是一个Rust库,提供模拟景观演化过程的方法,以创建具有合理地貌的真实地形数据。
给定一个平面图,每个节点分配了地形参数,fastlem运行模拟并将高程分配给图作为输出。
fastlem网页模拟器 可用于尝试使用fastlem手动创建虚拟地形。
安装
[!警告] 此项目目前正在开发中。在
0.1.*
期间,接口可能会发生很大变化。建议详细指定版本。
[dependencies]
fastlem = "0.1.4"
关于模拟
fastlem遵循 Salève 模型[1],这是一个用于模拟二维景观演化的分析模型。创建排水网络的算法遵循Guillaume Cordonnier、Jean Braun、Marie-Paule Cani、Bedrich Benes、Eric Galin等人[2]的方法。
构建图
地形数据表示为平面图。此图结构用于计算地形生成的所有地形模拟。
对于具有二维模型的fastlem,需要 TerrainModel2DBulider
从给定的站点构建图,作为 TerrainModel2D
。您可以选择使用 relaxate_sites
通过Lloyd算法将站点移动到大约相等的位置。
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();
创建地形生成器
在开始地形生成之前,需要 TerrainGenerator
使用平面图并将地形参数分配给每个站点。
let terrain_generator = TerrainGenerator::default()
.set_model(model)
.set_parameters(
(0..num)
.map(|_| TopographicalParameters::default().set_erodibility(1.0))
.collect::<_>(),
);
- is_outlet 表示该站点是否可以是出口(包括海洋)或不是。如果
is_outlet
,则高程始终设置为0.0。 - erodibility 是站点的侵蚀性。这是确定地形形状的主要参数。
生成地形
let terrain = terrain_generator.generate().unwrap();
通过调用 TerrainGenerator::generate()
生成地形。
获取高程
通常,您可以通过调用 [Terrain]::sites()
和 [Terrain]::elevations()
来获取网站和海拔高度作为向量。
每个向量的索引相互对应。
let sites = terrain.sites();
let elevations = terrain.elevations();
// print
for i in 0..sites.len() {
println!(
"Site: ({}, {}), Elevation: {}",
sites[i].x, sites[i].y, elevations[i]
);
}
您还可以通过调用 Terrain2D::get_elevation(Site2D)
在2D表面模型中查询特定地点的海拔高度。
let site = Site2D { x, y };
let elevation = terrain.get_elevation(&site);
请注意,此方法使用自然邻域插值(使用 naturalneighbor 包)在站点之间插值特定海拔,大约需要 O(logN) 的时间。
以下是一个使用 get_elevation
创建生成的地形图像的示例
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();
参考
[1] Steer, P.: 简报:二维景观演化的分析模型,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, 等等。从构造隆升和河流侵蚀生成大规模地形。计算机图形学论坛,2016,Proc. EUROGRAPHICS 2016,35 (2),pp.165-175. ⟨10.1111/cgf.12820⟩. ⟨hal-01262376⟩
贡献
欢迎贡献。如果您有任何问题或建议,请随意打开一个问题或拉取请求。
文档
此项目的 API参考 可用。
以下是一些示例,阅读 landscape_evolution.rs 是第一步。
许可
MPL-2.0
示例预览
简单景观演化 | 简单地形生成 |
---|---|
![]() |
![]() |
$cargo run --examplelandscape_evolution --release |
$cargo run --exampleterrain_generation --release |
高级地形生成 | 从给定参数生成地形 |
---|---|
![]() |
![]() |
$cargo run --exampleterrain_generation_advanced --release |
$cargo run --examplesample_terrain --release |
依赖
~4MB
~57K SLoC