apsis-rs/crates/rf/apsis-atmosphere/tests/geometry.rs

69 lines
2.1 KiB
Rust

//! Tests for the atmospheric path geometry.
//!
//! 大气路径几何的测试。
use apsis_atmosphere::{air_mass, elevation_from_zenith, zenith_to_elevation};
use core::f64::consts::{FRAC_PI_2, FRAC_PI_4, FRAC_PI_6};
const TOLERANCE: f64 = 1e-12;
#[test]
fn the_zenith_has_unit_air_mass() {
assert!((air_mass(FRAC_PI_2) - 1.0).abs() < TOLERANCE);
assert!((air_mass(zenith_to_elevation(0.0)) - 1.0).abs() < TOLERANCE);
}
#[test]
fn the_air_mass_is_the_cosecant_of_the_elevation() {
for elevation in [FRAC_PI_6, FRAC_PI_4, FRAC_PI_2, 0.2, 1.0, 1.4] {
let expected = 1.0 / elevation.sin();
assert!(
(air_mass(elevation) - expected).abs() < 1e-9,
"elevation {elevation}"
);
}
}
#[test]
fn known_elevations_give_known_air_masses() {
// Thirty degrees is a cosecant of two.
// 三十度的余割为二。
assert!((air_mass(FRAC_PI_6) - 2.0).abs() < 1e-9);
// Forty five degrees is the square root of two.
// 四十五度是根号二。
assert!((air_mass(FRAC_PI_4) - 2.0_f64.sqrt()).abs() < 1e-9);
// Ten degrees is about 5.76.
// 十度约为 5.76。
assert!((air_mass(10.0_f64.to_radians()) - 5.758_8).abs() < 1e-3);
}
#[test]
fn a_higher_elevation_has_a_smaller_air_mass() {
let low = air_mass(5.0_f64.to_radians());
let high = air_mass(80.0_f64.to_radians());
assert!(low > high);
}
#[test]
fn the_air_mass_is_infinite_at_or_below_the_horizon() {
assert!(air_mass(0.0).is_infinite());
assert!(air_mass(-0.1).is_infinite());
}
#[test]
fn elevation_and_zenith_angle_are_complementary() {
for angle in [0.0, FRAC_PI_6, FRAC_PI_4, 1.0, FRAC_PI_2] {
let elevation = elevation_from_zenith(angle);
assert!((elevation + angle - FRAC_PI_2).abs() < TOLERANCE);
assert!((zenith_to_elevation(elevation) - angle).abs() < TOLERANCE);
}
}
#[test]
fn the_conversions_are_involutions() {
for angle in [0.0, 0.3, 1.0, 1.5, FRAC_PI_2] {
assert!((zenith_to_elevation(elevation_from_zenith(angle)) - angle).abs() < TOLERANCE);
assert!((elevation_from_zenith(zenith_to_elevation(angle)) - angle).abs() < TOLERANCE);
}
}