use crate::physics::basic::{Coef, Momentum, MomentumType, Vector3};
use crate::utils::float;
impl Vector3<Momentum> {
pub fn limit_float(&self, threshold: f64, momentum_type: MomentumType) -> Self {
let (x, y, z) = match momentum_type {
MomentumType::KgMperSecond => (
float::limit_float(self.x.as_kg_m_s(), threshold),
float::limit_float(self.y.as_kg_m_s(), threshold),
float::limit_float(self.z.as_kg_m_s(), threshold),
),
MomentumType::KgKmperSecond => (
float::limit_float(self.x.as_kg_km_s(), threshold),
float::limit_float(self.y.as_kg_km_s(), threshold),
float::limit_float(self.z.as_kg_km_s(), threshold),
),
};
Self {
x: Momentum { v: x, default_type: momentum_type },
y: Momentum { v: y, default_type: momentum_type },
z: Momentum { v: z, default_type: momentum_type },
}
}
pub fn to_vector3_coef(&self, momentum_type: MomentumType) -> Vector3<Coef> {
match momentum_type {
MomentumType::KgMperSecond => {
let (x, y, z) = (self.x.as_kg_m_s(), self.y.as_kg_m_s(), self.z.as_kg_m_s());
Vector3::<Coef>::from_array([x, y, z])
}
MomentumType::KgKmperSecond => {
let (x, y, z) = (self.x.as_kg_km_s(), self.y.as_kg_km_s(), self.z.as_kg_km_s());
Vector3::<Coef>::from_array([x, y, z])
}
}
}
pub fn from_vector_coef(coef: Vector3<Coef>, momentum_type: MomentumType) -> Vector3<Momentum> {
let x = Momentum {
v: coef.x.v,
default_type: momentum_type,
};
let y = Momentum {
v: coef.y.v,
default_type: momentum_type,
};
let z = Momentum {
v: coef.z.v,
default_type: momentum_type,
};
Vector3::new(x, y, z)
}
pub fn from_array_with_unit(array: [f64; 3], momentum_type: MomentumType) -> Vector3<Momentum> {
let [x, y, z] = array;
let x = Momentum {
v: x,
default_type: momentum_type,
};
let y = Momentum {
v: y,
default_type: momentum_type,
};
let z = Momentum {
v: z,
default_type: momentum_type,
};
Vector3::new(x, y, z)
}
}
#[cfg(test)]
mod tests {
use super::*;
use approx::assert_relative_eq;
#[test]
fn test_limit_float() {
let v = Vector3::new(
Momentum::from_kg_m_s(1.0),
Momentum::from_kg_m_s(-5.0),
Momentum::from_kg_m_s(3.0),
);
let result = v.limit_float(3.0, MomentumType::KgMperSecond);
assert_relative_eq!(result.x.as_kg_m_s(), 1.0);
assert_relative_eq!(result.y.as_kg_m_s(), -3.0);
assert_relative_eq!(result.z.as_kg_m_s(), 3.0);
let result = v.limit_float(1e10, MomentumType::KgKmperSecond);
assert_relative_eq!(result.x.as_kg_km_s(), 0.001);
assert_relative_eq!(result.y.as_kg_km_s(), -0.005);
assert_relative_eq!(result.z.as_kg_km_s(), 0.003);
}
#[test]
fn test_to_vector3_coef_kg_m_s() {
let momentum_vec = Vector3::new(
Momentum::from_kg_m_s(10.0),
Momentum::from_kg_m_s(20.0),
Momentum::from_kg_m_s(30.0),
);
let coef_vec = momentum_vec.to_vector3_coef(MomentumType::KgMperSecond);
assert_relative_eq!(coef_vec.x, 10.0);
assert_relative_eq!(coef_vec.y, 20.0);
assert_relative_eq!(coef_vec.z, 30.0);
}
#[test]
fn test_to_vector3_coef_kg_km_s() {
let momentum_vec = Vector3::new(
Momentum::from_kg_m_s(1000.0), Momentum::from_kg_m_s(2000.0), Momentum::from_kg_m_s(3000.0), );
let coef_vec = momentum_vec.to_vector3_coef(MomentumType::KgKmperSecond);
assert_relative_eq!(coef_vec.x, 1.0);
assert_relative_eq!(coef_vec.y, 2.0);
assert_relative_eq!(coef_vec.z, 3.0);
}
#[test]
fn test_from_vector_coef_kg_m_s() {
let coef_vec = Vector3::new(
Coef::new(10.0),
Coef::new(20.0),
Coef::new(30.0),
);
let momentum_vec = Vector3::<Momentum>::from_vector_coef(coef_vec, MomentumType::KgMperSecond);
assert_relative_eq!(momentum_vec.x.as_kg_m_s(), 10.0);
assert_relative_eq!(momentum_vec.y.as_kg_m_s(), 20.0);
assert_relative_eq!(momentum_vec.z.as_kg_m_s(), 30.0);
}
#[test]
fn test_from_vector_coef_kg_km_s() {
let coef_vec = Vector3::new(
Coef::new(1.0),
Coef::new(2.0),
Coef::new(3.0),
);
let momentum_vec = Vector3::<Momentum>::from_vector_coef(coef_vec, MomentumType::KgKmperSecond);
assert_relative_eq!(momentum_vec.x.as_kg_km_s(), 1.0);
assert_relative_eq!(momentum_vec.y.as_kg_km_s(), 2.0);
assert_relative_eq!(momentum_vec.z.as_kg_km_s(), 3.0);
}
#[test]
fn test_from_vector_coef_roundtrip() {
let original_momentum_vec = Vector3::new(
Momentum::from_kg_m_s(10.0),
Momentum::from_kg_m_s(20.0),
Momentum::from_kg_m_s(30.0),
);
let coef_vec = original_momentum_vec.to_vector3_coef(MomentumType::KgMperSecond);
let reconstructed_momentum_vec = Vector3::<Momentum>::from_vector_coef(coef_vec, MomentumType::KgMperSecond);
assert_relative_eq!(original_momentum_vec.x.as_kg_m_s(), reconstructed_momentum_vec.x.as_kg_m_s());
assert_relative_eq!(original_momentum_vec.y.as_kg_m_s(), reconstructed_momentum_vec.y.as_kg_m_s());
assert_relative_eq!(original_momentum_vec.z.as_kg_m_s(), reconstructed_momentum_vec.z.as_kg_m_s());
}
#[test]
fn test_from_array_with_unit() {
let array = [10.0, 20.0, 30.0];
let momentum_vec = Vector3::<Momentum>::from_array_with_unit(array, MomentumType::KgMperSecond);
assert_relative_eq!(momentum_vec.x.as_kg_m_s(), 10.0);
assert_relative_eq!(momentum_vec.y.as_kg_m_s(), 20.0);
assert_relative_eq!(momentum_vec.z.as_kg_m_s(), 30.0);
let array = [1.0, 2.0, 3.0];
let momentum_vec = Vector3::<Momentum>::from_array_with_unit(array, MomentumType::KgKmperSecond);
assert_relative_eq!(momentum_vec.x.as_kg_km_s(), 1.0);
assert_relative_eq!(momentum_vec.y.as_kg_km_s(), 2.0);
assert_relative_eq!(momentum_vec.z.as_kg_km_s(), 3.0);
}
}