use crate::units::{Distance, Force, Length};
use crate::{Direction, Magnitude};
#[derive(Clone, Copy, Debug)]
pub struct Moment {
pub d: Direction,
}
impl Moment {
#[inline]
pub const fn new(d: Direction) -> Self {
Self { d }
}
#[inline]
pub fn m(&self) -> Magnitude {
self.d.magnitude()
}
}
pub type Torque = Moment;
impl Moment {
pub fn from_force_distance(f: Force, d: Distance) -> Self {
Self::new(f.d * d.m())
}
#[inline]
pub fn from_distance_force(d: Distance, f: Force) -> Self {
Self::from_force_distance(f, d)
}
#[inline]
pub fn calc_distance(&self, f: Force) -> Distance {
Length::new(self.m() / f.m())
}
#[inline]
pub fn calc_force(&self, d: Distance) -> Force {
Force::new(self.d / d.m())
}
}
impl_vector_methods_2units![
Moment,
q1a = N,
q2a = m,
Q1a = newtons,
Q2a = metre,
Ja = per
];
#[cfg(test)]
mod tests {
use {super::*, float_eq::assert_float_eq};
#[test]
fn moment_formulas() {
let moment =
Moment::from_force_distance(Force::new(Direction::new(30., 0., 0.)), Length::new(0.2));
assert_float_eq!(6., moment.m(), r2nd <= Magnitude::EPSILON);
assert_float_eq!(
0.2,
moment
.calc_distance(Force::new(Direction::new(30., 0., 0.)))
.m(),
r2nd <= Magnitude::EPSILON
);
assert_float_eq!(
30.,
moment.calc_force(Length::new(0.2)).m(),
r2nd <= Magnitude::EPSILON
);
}
}