use qtty::angular::Radians;
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Fov {
Conical {
half_angle: Radians,
},
Rectangular {
across_track: Radians,
along_track: Radians,
},
}
impl Fov {
pub fn contains_boresight(&self, off_axis: Radians) -> bool {
let abs_off = off_axis.abs();
match self {
Fov::Conical { half_angle } => abs_off <= *half_angle,
Fov::Rectangular {
across_track,
along_track,
} => {
let half_x = *across_track / 2.0;
let half_y = *along_track / 2.0;
let bound = if half_x <= half_y { half_x } else { half_y };
abs_off <= bound
}
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Instrument {
pub id: String,
pub fov: Fov,
}
impl Instrument {
pub fn new(id: impl Into<String>, fov: Fov) -> Self {
Self { id: id.into(), fov }
}
}
#[cfg(test)]
mod tests {
use super::*;
use qtty::Quantity;
#[test]
fn fov_conical_contains_axis() {
let fov = Fov::Conical {
half_angle: Quantity::new(0.1),
};
assert!(fov.contains_boresight(Quantity::new(0.0)));
assert!(fov.contains_boresight(Quantity::new(0.099)));
assert!(!fov.contains_boresight(Quantity::new(0.2)));
}
#[test]
fn fov_rectangular_uses_smaller_half_angle() {
let fov = Fov::Rectangular {
across_track: Quantity::new(0.2),
along_track: Quantity::new(0.4),
};
assert!(fov.contains_boresight(Quantity::new(0.0)));
assert!(fov.contains_boresight(Quantity::new(0.09)));
assert!(!fov.contains_boresight(Quantity::new(0.15)));
}
#[test]
fn instrument_construction_preserves_id() {
let inst = Instrument::new(
"demo",
Fov::Conical {
half_angle: Quantity::new(0.1),
},
);
assert_eq!(inst.id, "demo");
}
}