use crate::physics::orbit::MERCURY_RADIUS;
use crate::terrain::heightmap::Heightmap;
pub struct ElevationGrid {
pub rows: usize,
pub cols: usize,
pub lat_min: f64,
pub lat_max: f64,
pub lon_min: f64,
pub lon_max: f64,
pub data: Vec<f64>,
}
impl ElevationGrid {
pub fn generate(
lat_min: f64,
lat_max: f64,
lon_min: f64,
lon_max: f64,
rows: usize,
cols: usize,
) -> Self {
let hmap = Heightmap::new(2048);
let mut data = Vec::with_capacity(rows * cols);
for r in 0..rows {
let lat = lat_min + (r as f64 / (rows - 1).max(1) as f64) * (lat_max - lat_min);
for c in 0..cols {
let lon = lon_min + (c as f64 / (cols - 1).max(1) as f64) * (lon_max - lon_min);
data.push(hmap.sample(lat, lon));
}
}
Self {
rows,
cols,
lat_min,
lat_max,
lon_min,
lon_max,
data,
}
}
pub fn get(&self, row: usize, col: usize) -> f64 {
self.data[row * self.cols + col]
}
pub fn min_elevation(&self) -> f64 {
self.data.iter().cloned().fold(f64::INFINITY, f64::min)
}
pub fn max_elevation(&self) -> f64 {
self.data.iter().cloned().fold(f64::NEG_INFINITY, f64::max)
}
pub fn mean_elevation(&self) -> f64 {
self.data.iter().sum::<f64>() / self.data.len() as f64
}
}
pub fn elevation(lat: f64, lon: f64) -> f64 {
let hmap = Heightmap::new(2048);
hmap.sample(lat, lon)
}
pub fn radius_at(lat: f64, lon: f64) -> f64 {
MERCURY_RADIUS + elevation(lat, lon)
}