use std::f64::consts::PI;
use std::ops::{Add, Div, Mul, Neg, Sub};
use super::*;
impl AngularAcceleration {
pub fn from_rad_per_second2(v: f64) -> Self {
AngularAcceleration {
default_type: AngularAccelerationType::RadperSecond2,
v,
}
}
pub fn from_deg_per_second2(v: f64) -> Self {
AngularAcceleration {
default_type: AngularAccelerationType::DegPerSecond2,
v,
}
}
pub fn as_rad_per_second2(&self) -> f64 {
return match self.default_type {
AngularAccelerationType::RadperSecond2 => self.v,
AngularAccelerationType::DegPerSecond2 => {
self.v * PI / 180.0
}
};
}
pub fn as_deg_per_second2(&self) -> f64 {
return match self.default_type {
AngularAccelerationType::RadperSecond2 => self.v * 180.0 / PI,
AngularAccelerationType::DegPerSecond2 => self.v,
};
}
}
impl PhysicalQuantity for AngularAcceleration {
fn as_any(&self) -> &dyn Any {
self
}
fn is_zero(&self) -> bool {
self.v == 0.0
}
fn default_unit_value(&self) -> f64 {
self.as_rad_per_second2()
}
fn set_value(&mut self, value: f64) {
self.v = value;
}
fn unit_display_name(&self) -> String {
"AngularAcceleration (rad/s²)".to_string()
}
}
impl Div<chrono::TimeDelta> for AngularAcceleration {
type Output = AngularVelocity;
fn div(self, rhs: chrono::TimeDelta) -> Self::Output {
let v = self.as_rad_per_second2() / time_delta_to_secs_f64(&rhs);
AngularVelocity::from_rad_per_second(v)
}
}
impl Add for AngularAcceleration {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
let v = self.as_rad_per_second2() + rhs.as_rad_per_second2();
AngularAcceleration::from_rad_per_second2(v)
}
}
impl<'a, 'b> Add<&'b AngularAcceleration> for &'a AngularAcceleration {
type Output = AngularAcceleration;
fn add(self, rhs: &'b AngularAcceleration) -> Self::Output { AngularAcceleration::from_rad_per_second2(self.as_rad_per_second2() + rhs.as_rad_per_second2()) }
}
impl<'a> Add<&'a AngularAcceleration> for AngularAcceleration {
type Output = AngularAcceleration;
fn add(self, rhs: &'a AngularAcceleration) -> Self::Output { AngularAcceleration::from_rad_per_second2(self.as_rad_per_second2() + rhs.as_rad_per_second2()) }
}
impl<'a> Add<AngularAcceleration> for &'a AngularAcceleration {
type Output = AngularAcceleration;
fn add(self, rhs: AngularAcceleration) -> Self::Output { AngularAcceleration::from_rad_per_second2(self.as_rad_per_second2() + rhs.as_rad_per_second2()) }
}
impl Add<f64> for AngularAcceleration {
type Output = Self;
fn add(self, rhs: f64) -> Self::Output {
let v = self.v + rhs;
AngularAcceleration {
v,
default_type: self.default_type,
}
}
}
impl Sub for AngularAcceleration {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
let v = self.as_rad_per_second2() - rhs.as_rad_per_second2();
AngularAcceleration::from_rad_per_second2(v)
}
}
impl<'a, 'b> Sub<&'b AngularAcceleration> for &'a AngularAcceleration {
type Output = AngularAcceleration;
fn sub(self, rhs: &'b AngularAcceleration) -> Self::Output { AngularAcceleration::from_rad_per_second2(self.as_rad_per_second2() - rhs.as_rad_per_second2()) }
}
impl<'a> Sub<&'a AngularAcceleration> for AngularAcceleration {
type Output = AngularAcceleration;
fn sub(self, rhs: &'a AngularAcceleration) -> Self::Output { AngularAcceleration::from_rad_per_second2(self.as_rad_per_second2() - rhs.as_rad_per_second2()) }
}
impl<'a> Sub<AngularAcceleration> for &'a AngularAcceleration {
type Output = AngularAcceleration;
fn sub(self, rhs: AngularAcceleration) -> Self::Output { AngularAcceleration::from_rad_per_second2(self.as_rad_per_second2() - rhs.as_rad_per_second2()) }
}
impl Sub<f64> for AngularAcceleration {
type Output = Self;
fn sub(self, rhs: f64) -> Self::Output {
let v = self.v - rhs;
AngularAcceleration {
v,
default_type: self.default_type,
}
}
}
impl Mul<chrono::TimeDelta> for AngularAcceleration {
type Output = AngularVelocity;
fn mul(self, rhs: chrono::TimeDelta) -> Self::Output {
let v = self.as_rad_per_second2() * time_delta_to_secs_f64(&rhs);
AngularVelocity::from_rad_per_second(v)
}
}
impl<'a> Mul<chrono::TimeDelta> for &'a AngularAcceleration {
type Output = AngularVelocity;
fn mul(self, rhs: chrono::TimeDelta) -> Self::Output { AngularVelocity::from_rad_per_second(self.as_rad_per_second2() * time_delta_to_secs_f64(&rhs)) }
}
impl<'a> Mul<&'a chrono::TimeDelta> for AngularAcceleration {
type Output = AngularVelocity;
fn mul(self, rhs: &'a chrono::TimeDelta) -> Self::Output { AngularVelocity::from_rad_per_second(self.as_rad_per_second2() * time_delta_to_secs_f64(rhs)) }
}
impl<'a, 'b> Mul<&'b chrono::TimeDelta> for &'a AngularAcceleration {
type Output = AngularVelocity;
fn mul(self, rhs: &'b chrono::TimeDelta) -> Self::Output { AngularVelocity::from_rad_per_second(self.as_rad_per_second2() * time_delta_to_secs_f64(rhs)) }
}
impl Mul<Distance> for AngularAcceleration {
type Output = Acceleration;
fn mul(self, rhs: Distance) -> Self::Output {
let v = self.as_rad_per_second2() * rhs.as_m();
Acceleration::from_m_per_s2(v)
}
}
impl<'a, 'b> Mul<&'b Distance> for &'a AngularAcceleration {
type Output = Acceleration;
fn mul(self, rhs: &'b Distance) -> Self::Output { Acceleration::from_m_per_s2(self.as_rad_per_second2() * rhs.as_m()) }
}
impl<'a> Mul<&'a Distance> for AngularAcceleration {
type Output = Acceleration;
fn mul(self, rhs: &'a Distance) -> Self::Output { Acceleration::from_m_per_s2(self.as_rad_per_second2() * rhs.as_m()) }
}
impl<'a> Mul<Distance> for &'a AngularAcceleration {
type Output = Acceleration;
fn mul(self, rhs: Distance) -> Self::Output { Acceleration::from_m_per_s2(self.as_rad_per_second2() * rhs.as_m()) }
}
impl Mul<f64> for AngularAcceleration {
type Output = Self;
fn mul(self, rhs: f64) -> Self::Output {
let v = self.as_rad_per_second2() * rhs;
Self::from_rad_per_second2(v)
}
}
impl Div<f64> for AngularAcceleration {
type Output = Self;
fn div(self, rhs: f64) -> Self::Output {
let v = self.as_rad_per_second2() / rhs;
Self::from_rad_per_second2(v)
}
}
impl Mul<AngularAcceleration> for f64 {
type Output = AngularAcceleration;
fn mul(self, rhs: AngularAcceleration) -> Self::Output {
rhs * self
}
}
impl Div<AngularAcceleration> for f64 {
type Output = AngularAcceleration;
fn div(self, rhs: AngularAcceleration) -> Self::Output {
let v = self / rhs.v;
AngularAcceleration {
default_type: rhs.default_type,
v: v,
}
}
}
impl Mul<Coef> for AngularAcceleration {
type Output = Self;
fn mul(self, rhs: Coef) -> Self::Output {
let v = self.as_rad_per_second2() * rhs.get_value();
Self::from_rad_per_second2(v)
}
}
impl Div<Coef> for AngularAcceleration {
type Output = Self;
fn div(self, rhs: Coef) -> Self::Output {
let v = self.as_rad_per_second2() / rhs.get_value();
Self::from_rad_per_second2(v)
}
}
impl Neg for AngularAcceleration {
type Output = Self;
fn neg(self) -> Self::Output {
let v = -self.as_rad_per_second2();
Self::from_rad_per_second2(v)
}
}
#[cfg(test)]
mod tests {
use chrono::TimeDelta;
use approx::assert_relative_eq;
use super::*;
#[test]
fn test_angular_acceleration_from() {
let alpha1 = AngularAcceleration::from_rad_per_second2(6.0 * PI);
assert_eq!(alpha1.default_type, AngularAccelerationType::RadperSecond2);
assert_eq!(alpha1.v, 6.0 * PI);
let alpha1 = AngularAcceleration::from_deg_per_second2(360.0);
assert_eq!(alpha1.default_type, AngularAccelerationType::DegPerSecond2);
assert_eq!(alpha1.v, 360.0);
}
#[test]
fn test_angular_acceleration_as() {
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
assert_relative_eq!(alpha1.as_rad_per_second2(), 1.0*PI);
assert_relative_eq!(alpha1.as_deg_per_second2(), 180.0);
let alpha1 = AngularAcceleration::from_deg_per_second2(180.0);
assert_eq!(alpha1.as_deg_per_second2(), 180.0);
assert_relative_eq!(alpha1.as_rad_per_second2(), PI);
}
#[test]
fn test_angular_acceleration_change() {
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let duration = time_delta_from_secs_f64(10.0);
let omg1 = alpha1 / duration;
assert_eq!(omg1.default_type, AngularVelocityType::RadperSecond);
assert_relative_eq!(omg1.as_rad_per_second(), 0.1 * PI);
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let distance = Distance::from_m(10.0);
let a1 = alpha1 * distance;
assert_relative_eq!(a1.as_m_per_s2(),10.0 * PI);
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let omg = alpha1 * duration;
assert_relative_eq!(omg.as_rad_per_second(), 10.0* PI);
}
#[test]
fn test_angular_acceleration_change_timedelta() {
let alpha = AngularAcceleration::from_rad_per_second2(PI);
let td = time_delta_from_secs_f64(10.0);
let omg = alpha / td;
assert_relative_eq!(omg.as_rad_per_second(), 0.1 * PI);
let neg_td = time_delta_from_secs_f64(-10.0);
let omg_neg = alpha / neg_td;
assert_relative_eq!(omg_neg.as_rad_per_second(), -0.1 * PI);
let omg2 = alpha * td;
assert_relative_eq!(omg2.as_rad_per_second(), 10.0 * PI);
let omg_neg2 = alpha * neg_td;
assert_relative_eq!(omg_neg2.as_rad_per_second(), -10.0 * PI);
}
#[test]
fn test_angular_acceleration_add() {
{
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let alpha2 = AngularAcceleration::from_rad_per_second2(PI + PI);
let alpha3 = alpha1 + alpha2;
assert_relative_eq!(alpha3.as_rad_per_second2(), 3.0 * PI);
let alpha1 = AngularAcceleration::from_deg_per_second2(100.0);
let alpha2 = AngularAcceleration::from_deg_per_second2(100.0);
let alpha3 = alpha1 + alpha2;
assert_relative_eq!(alpha3.as_deg_per_second2(), 200.0);
let alpha1 = AngularAcceleration::from_deg_per_second2(180.0);
let alpha2 = AngularAcceleration::from_rad_per_second2(PI);
let alpha3 = alpha1 + alpha2;
assert_relative_eq!(alpha3.as_deg_per_second2(), 360.0);
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let alpha2 = AngularAcceleration::from_deg_per_second2(180.0);
let alpha3 = alpha1 + alpha2;
assert_relative_eq!(alpha3.as_deg_per_second2(), 360.0);
}
{
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let alpha2 = alpha1 + PI;
assert_relative_eq!(alpha2.as_rad_per_second2(), 2.0*PI);
let alpha1 = AngularAcceleration::from_deg_per_second2(90.0);
let alpha2 = alpha1 + 90.0;
assert_relative_eq!(alpha2.as_deg_per_second2(), 180.0);
}
}
#[test]
fn test_angular_acceleration_sub() {
{
let alpha1 = AngularAcceleration::from_rad_per_second2(PI + PI);
let alpha2 = AngularAcceleration::from_rad_per_second2(PI);
let alpha3 = alpha1 - alpha2;
assert_relative_eq!(alpha3.as_rad_per_second2(), PI);
let alpha1 = AngularAcceleration::from_deg_per_second2(100.0);
let alpha2 = AngularAcceleration::from_deg_per_second2(100.0);
let alpha3 = alpha1 - alpha2;
assert_relative_eq!(alpha3.as_deg_per_second2(), 0.0);
let alpha1 = AngularAcceleration::from_deg_per_second2(180.0);
let alpha2 = AngularAcceleration::from_rad_per_second2(PI);
let alpha3 = alpha1 - alpha2;
assert_relative_eq!(alpha3.as_deg_per_second2(), 0.0);
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let alpha2 = AngularAcceleration::from_deg_per_second2(180.0);
let alpha3 = alpha1 - alpha2;
assert_relative_eq!(alpha3.as_deg_per_second2(), 0.0);
}
{
let alpha1 = AngularAcceleration::from_rad_per_second2(PI);
let alpha2 = alpha1 - PI;
assert_relative_eq!(alpha2.as_rad_per_second2(), 0.0);
let alpha1 = AngularAcceleration::from_deg_per_second2(90.0);
let alpha2 = alpha1 - 90.0;
assert_relative_eq!(alpha2.as_deg_per_second2(), 0.0);
}
}
#[test]
fn test_to_mul() {
let d1 = AngularAcceleration::from_rad_per_second2(1000.0);
let d2 = d1 * 2.0;
assert_eq!(d2.as_rad_per_second2(), 2000.0);
let d1 = AngularAcceleration::from_rad_per_second2(1000.0);
let d2 = d1 * Coef::new(2.0);
assert_eq!(d2.as_rad_per_second2(), 2000.0);
}
#[test]
fn test_to_div() {
let d1 = AngularAcceleration::from_rad_per_second2(1000.0);
let d2 = d1 / 2.0;
assert_eq!(d2.as_rad_per_second2(), 500.0);
let d1 = AngularAcceleration::from_rad_per_second2(1000.0);
let d2 = d1 / Coef::new(2.0);
assert_eq!(d2.as_rad_per_second2(), 500.0);
}
#[test]
fn test_as_any(){
let d1 = AngularAcceleration::from_rad_per_second2(1000.0);
let dw = d1.as_any();
let _d2 = dw.downcast_ref::<AngularAcceleration>().unwrap();
}
#[test]
fn test_is_zero(){
let d1 = AngularAcceleration::from_rad_per_second2(1000.0);
let d2 = AngularAcceleration::from_rad_per_second2(0.0);
assert_eq!(d1.is_zero(),false);
assert_eq!(d2.is_zero(),true);
}
#[test]
fn test_default_unit_value(){
let d1 = AngularAcceleration::from_rad_per_second2(1000.0);
assert_eq!(d1.default_unit_value(),1000.0);
let d1 = AngularAcceleration::from_deg_per_second2(180.0);
assert_eq!(d1.default_unit_value(),PI);
let mut d1 = AngularAcceleration::from_rad_per_second2(PI);
d1.set_value(1000.0);
assert_eq!(d1.default_unit_value(),1000.0);
}
#[test]
fn test_f64_mul_angular_acceleration() {
let a = AngularAcceleration::from_rad_per_second2(PI);
let result = 2.0 * a;
assert_relative_eq!(result.as_rad_per_second2(), 2.0 * PI);
let a = AngularAcceleration::from_deg_per_second2(90.0);
let result = 2.0 * a;
assert_relative_eq!(result.as_deg_per_second2(), 180.0);
}
#[test]
fn test_f64_div_angular_acceleration() {
let a = AngularAcceleration::from_rad_per_second2(PI);
let result = 2.0 * PI / a;
assert_relative_eq!(result.as_rad_per_second2(), 2.0);
let a = AngularAcceleration::from_deg_per_second2(180.0);
let result = 180.0 / a;
assert_relative_eq!(result.as_deg_per_second2(), 1.0);
}
#[test]
fn test_angular_acceleration_ref_ops() {
let a1 = AngularAcceleration::from_rad_per_second2(std::f64::consts::PI);
let a2 = AngularAcceleration::from_deg_per_second2(180.0); let s = &a1 + &a2;
assert_relative_eq!(s.as_rad_per_second2(), 2.0 * std::f64::consts::PI);
let d = &a1 - &a2;
assert_relative_eq!(d.as_rad_per_second2(), 0.0);
let v = &a1 * &TimeDelta::seconds(2);
assert_relative_eq!(v.as_rad_per_second(), 2.0 * std::f64::consts::PI);
let acc = &a1 * &Distance::from_m(2.0);
assert_relative_eq!(acc.as_m_per_s2(), 2.0 * std::f64::consts::PI);
let s2 = a1 + &a2;
assert_relative_eq!(s2.as_rad_per_second2(), 2.0 * std::f64::consts::PI);
let s3 = &a1 + a2;
assert_relative_eq!(s3.as_rad_per_second2(), 2.0 * std::f64::consts::PI);
let a2b = AngularAcceleration::from_deg_per_second2(180.0);
let d2 = a1 - &a2b;
assert_relative_eq!(d2.as_rad_per_second2(), 0.0);
let d3 = &a1 - a2b;
assert_relative_eq!(d3.as_rad_per_second2(), 0.0);
let dur = TimeDelta::seconds(2);
let w2 = a1 * &dur;
assert_relative_eq!(w2.as_rad_per_second(), 2.0 * std::f64::consts::PI);
let w3 = &a1 * dur;
assert_relative_eq!(w3.as_rad_per_second(), 2.0 * std::f64::consts::PI);
let td = time_delta_from_secs_f64(2.0);
let w4 = a1 * &td;
assert_relative_eq!(w4.as_rad_per_second(), 2.0 * std::f64::consts::PI);
let w5 = &a1 * td;
assert_relative_eq!(w5.as_rad_per_second(), 2.0 * std::f64::consts::PI);
let td2 = time_delta_from_secs_f64(2.0);
let w6 = &a1 * &td2;
assert_relative_eq!(w6.as_rad_per_second(), 2.0 * std::f64::consts::PI);
let acc2 = a1 * &Distance::from_m(2.0);
assert_relative_eq!(acc2.as_m_per_s2(), 2.0 * std::f64::consts::PI);
let acc3 = &a1 * Distance::from_m(2.0);
assert_relative_eq!(acc3.as_m_per_s2(), 2.0 * std::f64::consts::PI);
}
#[test]
fn test_angular_acceleration_neg() {
let a1 = AngularAcceleration::from_rad_per_second2(PI);
let neg_a1 = -a1;
assert_relative_eq!(neg_a1.as_rad_per_second2(), -PI);
let a2 = AngularAcceleration::from_deg_per_second2(-90.0);
let neg_a2 = -a2;
assert_relative_eq!(neg_a2.as_deg_per_second2(), 90.0);
let a3 = AngularAcceleration::from_rad_per_second2(0.0);
let neg_a3 = -a3;
assert_relative_eq!(neg_a3.as_rad_per_second2(), 0.0);
let a4 = AngularAcceleration::from_deg_per_second2(180.0);
let neg_a4 = -a4;
assert_relative_eq!(neg_a4.as_rad_per_second2(), -PI);
let a5 = AngularAcceleration::from_rad_per_second2(2.0 * PI);
let neg_a5 = -a5;
assert_relative_eq!(neg_a5.as_deg_per_second2(), -360.0);
}
}