pub struct BathymetryData {
pub resolution_arcsec: f64,
pub data: Vec<f64>,
pub rows: usize,
pub cols: usize,
}
impl BathymetryData {
pub fn global(resolution_arcsec: f64) -> Self {
let effective_res = resolution_arcsec.max(600.0);
let rows = (180.0 * 3600.0 / effective_res) as usize;
let cols = (360.0 * 3600.0 / effective_res) as usize;
let mut data = vec![0.0; rows * cols];
for r in 0..rows {
for c in 0..cols {
let lat = 90.0 - (r as f64 + 0.5) * effective_res / 3600.0;
let lon = -180.0 + (c as f64 + 0.5) * effective_res / 3600.0;
let elev = crate::terrain::heightmap::earth_elevation(lat, lon);
data[r * cols + c] = if elev < 0.0 { elev } else { 0.0 };
}
}
Self {
resolution_arcsec: effective_res,
data,
rows,
cols,
}
}
pub fn sample(&self, lat_deg: f64, lon_deg: f64) -> f64 {
let lat_frac = (lat_deg + 90.0) / 180.0;
let lon_frac = (lon_deg + 180.0) / 360.0;
let row =
((1.0 - lat_frac) * (self.rows - 1) as f64).clamp(0.0, (self.rows - 1) as f64) as usize;
let col = (lon_frac * (self.cols - 1) as f64).clamp(0.0, (self.cols - 1) as f64) as usize;
self.data.get(row * self.cols + col).copied().unwrap_or(0.0)
}
pub fn is_ocean(&self, lat_deg: f64, lon_deg: f64) -> bool {
self.sample(lat_deg, lon_deg) < 0.0
}
pub fn ocean_stats() -> OceanBasinStats {
OceanBasinStats {
avg_depth_m: 3_688.0,
max_depth_m: 10_994.0,
total_volume_km3: 1_335_000_000.0,
surface_area_km2: 361_132_000.0,
}
}
}
pub struct OceanBasinStats {
pub avg_depth_m: f64,
pub max_depth_m: f64,
pub total_volume_km3: f64,
pub surface_area_km2: f64,
}
pub struct OceanBasin {
pub name: String,
pub avg_depth_m: f64,
pub max_depth_m: f64,
pub area_km2: f64,
}
impl OceanBasin {
pub fn major_basins() -> Vec<Self> {
vec![
Self {
name: "Pacific".into(),
avg_depth_m: 4_280.0,
max_depth_m: 10_994.0,
area_km2: 165_250_000.0,
},
Self {
name: "Atlantic".into(),
avg_depth_m: 3_646.0,
max_depth_m: 8_376.0,
area_km2: 106_460_000.0,
},
Self {
name: "Indian".into(),
avg_depth_m: 3_741.0,
max_depth_m: 7_906.0,
area_km2: 70_560_000.0,
},
Self {
name: "Southern".into(),
avg_depth_m: 3_270.0,
max_depth_m: 7_236.0,
area_km2: 21_960_000.0,
},
Self {
name: "Arctic".into(),
avg_depth_m: 1_205.0,
max_depth_m: 5_550.0,
area_km2: 14_060_000.0,
},
]
}
}