34 lines
896 B
Rust
34 lines
896 B
Rust
use serde::{Deserialize, Serialize};
|
||
|
||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
||
pub struct HorizonPoint {
|
||
pub az_deg: i32,
|
||
pub alt_deg: f64,
|
||
}
|
||
|
||
/// Linear interpolation of horizon altitude at a given azimuth.
|
||
/// The profile must have points at every integer degree 0–359.
|
||
pub fn horizon_alt(az_deg: f64, profile: &[HorizonPoint]) -> f64 {
|
||
if profile.is_empty() {
|
||
return 15.0;
|
||
}
|
||
|
||
let az = az_deg.rem_euclid(360.0);
|
||
let lo_idx = az.floor() as usize % 360;
|
||
let hi_idx = (lo_idx + 1) % 360;
|
||
let frac = az.fract();
|
||
|
||
let lo_alt = profile
|
||
.iter()
|
||
.find(|p| p.az_deg == lo_idx as i32)
|
||
.map(|p| p.alt_deg)
|
||
.unwrap_or(15.0);
|
||
let hi_alt = profile
|
||
.iter()
|
||
.find(|p| p.az_deg == hi_idx as i32)
|
||
.map(|p| p.alt_deg)
|
||
.unwrap_or(15.0);
|
||
|
||
lo_alt + frac * (hi_alt - lo_alt)
|
||
}
|