venuss 0.0.2

Venus celestial simulation crate for the MilkyWay SolarSystem workspace
Documentation
pub const VENUS_FLATTENING: f64 = 0.0;
pub const VENUS_SEMI_MAJOR_M: f64 = crate::VENUS_EQUATORIAL_RADIUS;
pub const VENUS_SEMI_MINOR_M: f64 = crate::VENUS_POLAR_RADIUS;

#[derive(Debug, Clone, Copy)]
pub struct LatLon {
    pub lat_deg: f64,
    pub lon_deg: f64,
    pub alt_m: f64,
}

#[derive(Debug, Clone, Copy)]
pub struct Cartesian {
    pub x: f64,
    pub y: f64,
    pub z: f64,
}

impl LatLon {
    pub fn new(lat_deg: f64, lon_deg: f64, alt_m: f64) -> Self {
        Self {
            lat_deg,
            lon_deg,
            alt_m,
        }
    }

    pub fn to_cartesian(&self) -> Cartesian {
        let lat = self.lat_deg.to_radians();
        let lon = self.lon_deg.to_radians();
        let r = crate::VENUS_RADIUS + self.alt_m;
        Cartesian {
            x: r * lat.cos() * lon.cos(),
            y: r * lat.cos() * lon.sin(),
            z: r * lat.sin(),
        }
    }

    pub fn distance_to(&self, other: &LatLon) -> f64 {
        let lat1 = self.lat_deg.to_radians();
        let lat2 = other.lat_deg.to_radians();
        let dlat = (other.lat_deg - self.lat_deg).to_radians();
        let dlon = (other.lon_deg - self.lon_deg).to_radians();
        let a = (dlat / 2.0).sin().powi(2) + lat1.cos() * lat2.cos() * (dlon / 2.0).sin().powi(2);
        let c = 2.0 * a.sqrt().asin();
        crate::VENUS_RADIUS * c
    }
}

impl Cartesian {
    pub fn to_latlon(&self) -> LatLon {
        let r_xy = (self.x * self.x + self.y * self.y).sqrt();
        let lon = self.y.atan2(self.x).to_degrees();
        let lat = self.z.atan2(r_xy).to_degrees();
        let alt =
            (self.x * self.x + self.y * self.y + self.z * self.z).sqrt() - crate::VENUS_RADIUS;
        LatLon {
            lat_deg: lat,
            lon_deg: lon,
            alt_m: alt,
        }
    }
}