use rust_physics_engine::astrophysics::orbital_elements::OrbitalElements;
use rust_physics_engine::math::constants::{EARTH_MASS, EARTH_RADIUS, G};
use rust_physics_engine::math::Vec3;
use rust_physics_engine::propulsion::hohmann_delta_v;
fn main() {
let mu = G * EARTH_MASS;
let r = EARTH_RADIUS + 400e3;
let speed = (mu / r).sqrt();
let position = Vec3::new(r, 0.0, 0.0);
let velocity = Vec3::new(0.0, speed, 0.0);
let elements = OrbitalElements::from_state_vectors(position, velocity, mu);
println!("circular orbit at 400 km");
println!(" speed {:.0} m/s", speed);
println!(" semi-major {:.1} km", elements.semi_major_axis / 1e3);
println!(" eccentricity {:.2e}", elements.eccentricity);
println!(" period {:.1} min", elements.period(mu) / 60.0);
println!(" bound? {}", elements.is_bound());
assert!(elements.eccentricity < 1e-12);
let kepler = 2.0 * std::f64::consts::PI * (r.powi(3) / mu).sqrt();
assert!((elements.period(mu) - kepler).abs() < 1e-6);
let r_geo = 42_164e3;
let (dv1, dv2) = hohmann_delta_v(mu, r, r_geo);
println!();
println!("Hohmann transfer to geostationary");
println!(" burn 1 {:.0} m/s", dv1);
println!(" burn 2 {:.0} m/s", dv2);
println!(" total {:.0} m/s", dv1 + dv2);
assert!(dv1 > 0.0 && dv2 > 0.0);
assert!(dv1 > dv2);
let a_transfer = 0.5 * (r + r_geo);
let transfer_time = std::f64::consts::PI * (a_transfer.powi(3) / mu).sqrt();
println!(" flight time {:.1} hours", transfer_time / 3600.0);
let v_peri = (mu * (2.0 / r - 1.0 / a_transfer)).sqrt();
assert!((v_peri - (speed + dv1)).abs() < 1e-6);
println!();
println!("vis-viva at perigee agrees with circular speed + burn 1");
}