use super::*;
use coords::*;
use std::f64::consts::PI;
#[macro_export]
macro_rules! eq_frm_ecl {
($ecl_long: expr, $ecl_lat: expr, $oblq_eclip: expr) => {{
(astro::coords::asc_frm_ecl($ecl_long, $ecl_lat, $oblq_eclip),
astro::coords::dec_frm_ecl($ecl_long, $ecl_lat, $oblq_eclip))
}};
}
pub const MILLLISECONDS_IN_DAY: f64 = 1000.0 * 60.0 * 60.0 * 24.0;
pub const J1970: f64 = 2440588.0;
pub const J2000: f64 = 2451545.0;
pub const RAD: f64 = PI / 180.0;
pub const OBLIQUITY_OF_EARTH: f64 = RAD * 23.4397;
pub fn geo_frm_helio(julian_day: f64, helio_coords: CartesianCoordinates) -> CartesianCoordinates {
let earth_coords = vsop87::vsop87c::earth(julian_day);
return CartesianCoordinates {
x: helio_coords.x - earth_coords.x,
y: helio_coords.y - earth_coords.y,
z: helio_coords.z - earth_coords.z,
};
}
pub fn cart_frm_eq(eq_coords: EqCoordinates) -> CartesianCoordinates {
let x = eq_coords.dist * eq_coords.dec.cos() * eq_coords.ra.cos();
let y = eq_coords.dist * eq_coords.dec.cos() * eq_coords.ra.sin();
let z = eq_coords.dist * eq_coords.dec.sin();
return CartesianCoordinates { x: x, y: y, z: z };
}
pub fn helio_frm_geo(julian_day: f64, geo_coords: CartesianCoordinates) -> CartesianCoordinates {
let earth_coords = vsop87::vsop87c::earth(julian_day);
return CartesianCoordinates {
x: geo_coords.x + earth_coords.x,
y: geo_coords.y + earth_coords.y,
z: geo_coords.z + earth_coords.z,
};
}
pub fn ecl_frm_cart(x: f64, y: f64, z: f64) -> EclCoordinates {
let r = (x * x + y * y + z * z).sqrt();
let mut ra = (y).atan2(x);
ra = if ra >= 0.0 { ra } else { (2.0 * PI + ra) };
let dec = (z / r).asin();
return EclCoordinates {
lat: dec,
lng: ra,
dist: r,
};
}
pub fn eq_frm_cart(cart_coords: CartesianCoordinates) -> EqCoordinates {
let (x, y, z) = (cart_coords.x, cart_coords.y, cart_coords.z);
let r = (x * x + y * y + z * z).sqrt();
let mut ra = (y).atan2(x);
ra = if ra >= 0.0 { ra } else { (2.0 * PI + ra) };
let dec = (z / r).asin();
return EqCoordinates {
dec: dec.to_degrees(),
ra: ra.to_degrees(),
dist: r,
};
}
pub fn to_julian(date: DateTime<FixedOffset>) -> f64 {
let ts = (date.timestamp() as f64) * 1000.0;
return ts / MILLLISECONDS_IN_DAY - 0.5 + J1970;
}
pub fn from_julian(julian: f64) -> NaiveDateTime {
let millis = ((julian + 0.5 - J1970) * MILLLISECONDS_IN_DAY) as i64 / 1000;
return NaiveDateTime::from_timestamp(millis, 0);
}
pub fn julian_epoch_offset(julian: f64) -> f64 {
return julian - J2000;
}
pub fn right_ascension(l: f64, b: f64) -> f64 {
return (l.sin() * OBLIQUITY_OF_EARTH.cos() - b.tan() * OBLIQUITY_OF_EARTH.sin()).atan2(l.cos());
}
pub fn declination(l: f64, b: f64) -> f64 {
return (b.sin() * OBLIQUITY_OF_EARTH.cos() + b.cos() * OBLIQUITY_OF_EARTH.sin() * l.sin())
.asin();
}
pub fn ecliptic_longitude(mean_anomaly: f64) -> f64 {
let C = RAD *
(1.9148 * mean_anomaly.sin() + 0.02 * (2.0 * mean_anomaly).sin() +
0.0003 * (3.0 * mean_anomaly).sin());
let perihelion = RAD * 102.9372;
return mean_anomaly + C + perihelion + PI;
}
pub fn azimuth(H: f64, phi: f64, dec: f64) -> f64 {
return H.sin().atan2(H.cos() * phi.sin() - dec.tan() * phi.cos());
}
pub fn altitude(H: f64, phi: f64, dec: f64) -> f64 {
return (phi.sin() * dec.sin() + phi.cos() * dec.cos() * H.cos()).asin();
}
pub fn siderealTime(d: f64, lw: f64) -> f64 {
return RAD * (280.16 + 360.9856235 * d) - lw;
}
pub fn astroRefraction(h: f64) -> f64 {
let alt = if h < 0.0 { 0.0 } else { h };
return 0.0002967 / (alt + 0.00312536 / (alt + 0.08901179)).tan();
}