use nalgebra as na;
use na::{Vector3, Matrix3};
use crate::cosmos::gravity;
#[derive(Clone, Debug, PartialEq)]
pub struct SurfacePoint{
pub name: String,
pub body: gravity::Body,
pub pos_lla: Vector3<f64>,
}
#[derive(Clone, Debug, PartialEq)]
pub enum Frame{
Topocentric, GeocentricFixed, GeocentricInertial, Geodetic, AreocentricFixed, AreocentricInertial, Areodetic, Heliocentric }
impl SurfacePoint{
pub fn calc_surface_vel(&self) -> f64 {
let equatorial_vel: f64 = self.body.rotation_rate * self.body.eq_radius;
let tan_vel: f64 = (self.pos_lla[0].cos() * equatorial_vel).abs();
return tan_vel
}
pub fn calc_surface_radius(&self) -> Vector3<f64> {
let prime_vertical: f64 = self.body.calc_prime_vertical(self.pos_lla[0]);
let dir: Vector3<f64> = self.body.geodetic_to_xyz(self.pos_lla);
let radius: Vector3<f64> = (prime_vertical + self.pos_lla[2]) * dir;
return radius
}
pub fn calc_delta_v(
&self,
altitude: f64,
) -> f64 {
let radius: f64 = altitude + self.calc_surface_radius().norm();
let surface_vel: f64 = self.calc_surface_vel();
let delta_v: f64 = self.body.calc_orbital_velocity_mag(radius);
let net_delta_v: f64 = delta_v - surface_vel;
return net_delta_v
}
pub fn ecef_to_enu(&self, ecef_2: Vector3<f64>) -> Vector3<f64> {
let pos_lla: Vector3<f64> = self.pos_lla;
let pos_ecef: Vector3<f64> = self.body.geodetic_to_xyz(pos_lla);
let vec_ecef: Vector3<f64> = ecef_2 - pos_ecef;
let ecef_enu: Matrix3<f64> = Matrix3::new(
-pos_lla[1].sin(), pos_lla[1].cos(), 0.0,
-pos_lla[1].cos()*pos_lla[0].sin(), -pos_lla[1].sin()*pos_lla[0].sin(), pos_lla[0].cos(),
pos_lla[1].cos()*pos_lla[0].cos(), pos_lla[1].sin()*pos_lla[0].cos(), pos_lla[0].sin());
let enu: Vector3<f64> = ecef_enu * vec_ecef;
return enu
}
pub fn enu_to_ecef(&self, enu: Vector3<f64>) -> Vector3<f64> {
let pos_lla: Vector3<f64> = self.pos_lla;
let enu_ecef: Matrix3<f64> = Matrix3::new(
-pos_lla[1].sin(), -pos_lla[1].cos()*pos_lla[0].sin(), pos_lla[1].cos()*pos_lla[0].cos(),
pos_lla[1].cos(), -pos_lla[1].sin()*pos_lla[0].sin(), pos_lla[1].sin()*pos_lla[0].cos(),
0.0, pos_lla[0].cos(), pos_lla[0].sin()
);
let vec_ecef: Vector3<f64> = enu_ecef * enu;
let pos_ecef: Vector3<f64> = self.body.geodetic_to_xyz(self.pos_lla);
let ecef: Vector3<f64> = vec_ecef - pos_ecef;
return ecef
}
}