use crate::libs::cs::model::Cs;
use crate::libs::cs::utils::SignStrExt;
use crate::libs::tolerance;
impl Cs<3> {
#[rustfmt::skip] #[inline] pub fn rxy(&self) -> f64 { self.0[0].hypot(self.0[1]) }
#[rustfmt::skip] #[inline] pub fn rxz(&self) -> f64 { self.0[0].hypot(self.0[2]) }
#[rustfmt::skip] #[inline] pub fn ryz(&self) -> f64 { self.0[1].hypot(self.0[2]) }
#[rustfmt::skip] #[inline] pub fn rxyz(&self) -> f64 { self.0[0].hypot(self.0[1]).hypot(self.0[2]) }
#[rustfmt::skip] #[inline] pub fn arctan_y_x(&self) -> f64 { self.0[1].atan2(self.0[0]) }
#[rustfmt::skip] #[inline] pub fn arctan_z_x(&self) -> f64 { self.0[2].atan2(self.0[0]) }
#[rustfmt::skip] #[inline] pub fn arctan_z_y(&self) -> f64 { self.0[2].atan2(self.0[1]) }
#[rustfmt::skip] #[inline] pub fn arctan_x_y(&self) -> f64 { self.0[0].atan2(self.0[1]) }
#[rustfmt::skip] #[inline] pub fn arctan_x_z(&self) -> f64 { self.0[0].atan2(self.0[2]) }
#[rustfmt::skip] #[inline] pub fn arctan_y_z(&self) -> f64 { self.0[1].atan2(self.0[2]) }
#[rustfmt::skip] #[inline] pub fn arccos_x_rxyz(&self) -> f64 { let r = self.rxyz(); if tolerance::is_zero(r) { 0.0 } else { (self.0[0] / r).clamp(-1.0, 1.0).acos() } }
#[rustfmt::skip] #[inline] pub fn arccos_y_rxyz(&self) -> f64 { let r = self.rxyz(); if tolerance::is_zero(r) { 0.0 } else { (self.0[1] / r).clamp(-1.0, 1.0).acos() } }
#[rustfmt::skip] #[inline] pub fn arccos_z_rxyz(&self) -> f64 { let r = self.rxyz(); if tolerance::is_zero(r) { 0.0 } else { (self.0[2] / r).clamp(-1.0, 1.0).acos() } }
#[rustfmt::skip] #[inline] pub fn to_rf_from_xy(&self) -> Cs<2> { Cs([self.rxy(), self.arctan_y_x()]) }
#[rustfmt::skip] #[inline] pub fn to_rf_from_xz(&self) -> Cs<2> { Cs([self.rxz(), self.arctan_z_x()]) }
#[rustfmt::skip] #[inline] pub fn to_rf_from_yz(&self) -> Cs<2> { Cs([self.ryz(), self.arctan_z_y()]) }
#[rustfmt::skip] #[inline] pub fn to_rfx_from_xyz(&self) -> Cs<3> { Cs([self.ryz(), self.arctan_z_y(), self.0[0]]) }
#[rustfmt::skip] #[inline] pub fn to_rfy_from_xyz(&self) -> Cs<3> { Cs([self.rxz(), self.arctan_z_x(), self.0[1]]) }
#[rustfmt::skip] #[inline] pub fn to_rfz_from_xyz(&self) -> Cs<3> { Cs([self.rxy(), self.arctan_y_x(), self.0[2]]) }
#[rustfmt::skip] #[inline] pub fn to_rft_from_xyz(&self) -> Cs<3> { Cs([self.rxyz(), self.arctan_y_x(), self.arccos_z_rxyz()]) }
#[rustfmt::skip]
pub fn to_ecef_from_dms_sn_we(
sn_d: i16, sn_m: u8, sn_s: f32,
we_d: i16, we_m: u8, we_s: f32,
r: f64
) -> Self {
use crate::libs::angle::Angle;
let lat_rad = Angle::from_dms(sn_d, sn_m, sn_s).rad();
let lon_rad = Angle::from_dms(we_d, we_m, we_s).rad();
let (sin_lat, cos_lat) = lat_rad.sin_cos();
let (sin_lon, cos_lon) = lon_rad.sin_cos();
Cs([
r * cos_lat * cos_lon,
r * cos_lat * sin_lon,
r * sin_lat
])
}
#[rustfmt::skip]
pub fn to_dms_sn_we_from_xyz(&self) -> crate::libs::cs::model_coords::CoordsDmsNz90Ex0 {
use crate::libs::angle::Angle;
use crate::libs::tolerance;
let r = self.rxyz();
let (lat_rad, lon_rad) = if tolerance::is_zero(r) {
(0.0, 0.0)
} else {
(
(self.0[2] / r).clamp(-1.0, 1.0).asin(), self.0[1].atan2(self.0[0]) )
};
let lat_angle = Angle::from_rad(lat_rad);
let lon_angle = Angle::from_rad(lon_rad);
let (lat_d, lat_m, lat_s) = lat_angle.to_dms();
let (lon_d, lon_m, lon_s) = lon_angle.to_dms();
crate::libs::cs::model_coords::CoordsDmsNz90Ex0 {
sn_lat_d: lat_d as i8,
sn_lat_m: lat_m,
sn_lat_s: lat_s,
we_lon_d: lon_d,
we_lon_m: lon_m,
we_lon_s: lon_s,
}
}
#[rustfmt::skip] #[inline]
pub fn q(&self) -> u8 {
match (self.0[0] >= 0.0, self.0[1] >= 0.0, self.0[2] >= 0.0) {
(true, true, true) => 1, (false, true, true) => 2, (false, false, true) => 3, (true, false, true) => 4,
(true, true, false) => 5, (false, true, false) => 6, (false, false, false)=> 7, (true, false, false) => 8,
}
}
#[rustfmt::skip] #[inline]
pub fn q_sign(&self) -> [&'static str; 3] {
[self.0[0].sign_str(), self.0[1].sign_str(), self.0[2].sign_str()]
}
#[rustfmt::skip] #[inline] pub fn rxyz_sq(&self) -> f64 { self.0[0] * self.0[0] + self.0[1] * self.0[1] + self.0[2] * self.0[2] }
#[rustfmt::skip] #[inline] pub fn rxy_sq(&self) -> f64 { self.0[0] * self.0[0] + self.0[1] * self.0[1] }
#[rustfmt::skip] #[inline] pub fn rxz_sq(&self) -> f64 { self.0[0] * self.0[0] + self.0[2] * self.0[2] }
#[rustfmt::skip] #[inline] pub fn ryz_sq(&self) -> f64 { self.0[1] * self.0[1] + self.0[2] * self.0[2] }
#[rustfmt::skip] #[inline]
pub fn normalize_rxy_projection(&self) -> Cs<3> {
let r = self.rxy();
if tolerance::is_zero(r) { Cs([0.0, 0.0, self.0[2]]) } else { Cs([self.0[0] / r, self.0[1] / r, self.0[2]]) }
}
#[rustfmt::skip] #[inline]
pub fn normalize_rxz_projection(&self) -> Cs<3> {
let r = self.rxz();
if tolerance::is_zero(r) { Cs([0.0, self.0[1], 0.0]) } else { Cs([self.0[0] / r, self.0[1], self.0[2] / r]) }
}
#[rustfmt::skip] #[inline]
pub fn normalize_ryz_projection(&self) -> Cs<3> {
let r = self.ryz();
if tolerance::is_zero(r) { Cs([self.0[0], 0.0, 0.0]) } else { Cs([self.0[0], self.0[1] / r, self.0[2] / r]) }
}
#[rustfmt::skip] #[inline]
pub fn cross(&self, other: &Cs<3>) -> Cs<3> {
Cs([
self.0[1] * other.0[2] - self.0[2] * other.0[1],
self.0[2] * other.0[0] - self.0[0] * other.0[2],
self.0[0] * other.0[1] - self.0[1] * other.0[0]
])
}
}