use binding::{CDouble, CFloat}; use crate::real::Real; use crate::trig::radian::Radian; /// The available trigonometric functions. pub trait Trig: Real { /// Computes the cosine of this angle. /// /// ``` /// use sigils::{Constants, Radian, Trig}; /// /// let abs_difference: f64; /// let radians: Radian; /// /// radians = Radian::new(2.0f64 * f64::PI); /// abs_difference = (Trig::cos(radians) - 1.0f64).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` fn cos(arg: T) -> Self where T: Into>; /// Computes the sine of this angle. /// /// ``` /// use sigils::{Constants, Radian, Trig}; /// /// let abs_difference: f64; /// let radians: Radian; /// /// let radians: Radian = Radian::new(f64::PI / 2.0f64); /// let abs_difference = (Trig::sin(radians) - 1.0f64).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` fn sin(arg: T) -> Self where T: Into>; /// Computes the tangent of this angle. /// /// ``` /// use sigils::{Constants, Radian, Trig}; /// /// let abs_difference: f64; /// let radians: Radian; /// /// radians = Radian::new(f64::PI / 4.0f64); /// abs_difference = (Trig::tan(radians) - 1.0f64).abs(); /// /// assert!(abs_difference < 1e-14); /// ``` fn tan(arg: T) -> Self where T: Into>; /// Computes the arccosine of a number. Return value is in Degrees in /// the range [0, pi] or NaN if the number is outside the range /// [-1, 1]. /// ///``` /// use sigils::{Constants, Radian, Trig}; /// /// let angle: f64; /// let radians: Radian; /// let test: Radian; /// /// angle = f64::PI / 4.0f64; /// radians = Radian::new(angle); /// test = Trig::acos(Trig::cos(radians)); /// /// assert!((angle - *test) < 1e-10); ///``` fn acos(arg: Self) -> T where T: From>; /// Computes the arcsine of a number. Return value is in Degrees in /// the range [-pi/2, pi/2] or NaN if the number is /// outside the range [-1, 1]. /// ///``` /// use sigils::{Constants, Radian, Trig}; /// /// let angle: f64; /// let radians: Radian; /// let test: Radian; /// /// angle = f64::PI / 4.0f64; /// radians = Radian::new(angle); /// test = Trig::asin(Trig::sin(radians)); /// /// assert!((angle - *test) < 1e-10); ///``` fn asin(arg: Self) -> T where T: From>; /// Computes the arctangent of a number. Return value is in degrees in the /// range [-pi/2, pi/2]; /// ///``` /// use sigils::{Constants, Radian, Trig}; /// /// let angle: f64; /// let radians: Radian; /// let test: Radian; /// /// angle = f64::PI / 4.0f64; /// radians = Radian::new(angle); /// test = Trig::atan(Trig::tan(radians)); /// /// assert!((angle - *test) < 1e-10); ///``` fn atan(arg: Self) -> T where T: From>; /// Computes the four quadrant arctangent of y and x. fn atan2(y: Self, x: Self) -> T where T: From>; /// Hyperbolic cosine function. /// /// ``` /// use sigils::{Constants, Trig}; /// /// let f_val: f32; /// let g_val: f32; /// let abs_difference: f32; /// /// f_val = Trig::cosh(1.0f32); /// g_val = (f32::E * f32::E + 1.0f32) / (2.0f32 * f32::E); /// abs_difference = (f_val - g_val).abs(); /// /// // Solving cosh() at 1 gives this result /// assert!(abs_difference < 1.0e-10); /// ``` fn cosh(arg: Self) -> Self; /// Hyperbolic sine function. /// /// ``` /// use sigils::{Constants, Trig}; /// /// let f_val: f32; /// let g_val: f32; /// let abs_difference: f32; /// /// f_val = Trig::sinh(1.0f32); /// g_val = (f32::E * f32::E - 1.0f32) / (2.0f32 * f32::E); /// abs_difference = (f_val - g_val).abs(); /// /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` /// assert!(abs_difference < 1e-10); /// ``` fn sinh(arg: Self) -> Self; /// Hyperbolic tangent function. /// /// ``` /// use sigils::{Constants, Trig}; /// /// let f_val: f32; /// let g_val: f32; /// let abs_difference: f32; /// f_val = Trig::tanh(1.0f32); /// g_val = (1.0f32 - f32::E.powi(-2i32)) / (1.0f32 + f32::E.powi(-2i32)); /// abs_difference = (f_val - g_val).abs(); /// /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` /// assert!(abs_difference < 1.0e-6); /// ``` fn tanh(arg: Self) -> Self; /// Inverse hyperbolic cosine function. fn acosh(arg: Self) -> Self; /// Inverse hyperbolic sine function. fn asinh(arg: Self) -> Self; /// Inverse hyperbolic tangent function. fn atanh(arg: Self) -> Self; } impl Trig for f32 { fn cos(arg: T) -> Self where T: Into> { unsafe { ::pact::math::cosf(*arg.into() as CFloat) as Self } } fn sin(arg: T) -> Self where T: Into> { unsafe { ::pact::math::sinf(*arg.into() as CFloat) as Self } } fn tan(arg: T) -> Self where T: Into> { unsafe { ::pact::math::tanf(*arg.into() as CFloat) as Self } } fn acos(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::math::acosf(arg as CFloat) as Self).into() } } fn asin(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::math::asinf(arg as CFloat) as Self).into() } } fn atan(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::math::atanf(arg as CFloat) as Self).into() } } fn atan2(y: Self, x: Self) -> T where T: From> { unsafe { Radian::new( ::pact::math::atan2f(y as CFloat, x as CFloat) as Self).into() } } fn cosh(arg: Self) -> Self { unsafe { ::pact::math::coshf(arg as CFloat) as Self } } fn sinh(arg: Self) -> Self { unsafe { ::pact::math::sinhf(arg as CFloat) as Self } } fn tanh(arg: Self) -> Self { unsafe { ::pact::math::tanhf(arg as CFloat) as Self } } fn acosh(arg: Self) -> Self { unsafe { ::pact::math::acoshf(arg as CFloat) as Self } } fn asinh(arg: Self) -> Self { unsafe { ::pact::math::asinhf(arg as CFloat) as Self } } fn atanh(arg: Self) -> Self { unsafe { ::pact::math::atanhf(arg as CFloat) as Self } } } impl Trig for f64 { fn cos(arg: T) -> Self where T: Into> { unsafe { ::pact::math::cos(*arg.into() as CDouble) as Self } } fn sin(arg: T) -> Self where T: Into> { unsafe { ::pact::math::sin(*arg.into() as CDouble) as Self } } fn tan(arg: T) -> Self where T: Into> { unsafe { ::pact::math::tan(*arg.into() as CDouble) as Self } } fn acos(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::math::acos(arg as CDouble) as Self).into() } } fn asin(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::math::asin(arg as CDouble) as Self).into() } } fn atan(arg: Self) -> T where T: From> { unsafe { Radian::new(::pact::math::atan(arg as CDouble) as Self).into() } } fn atan2(y: Self, x: Self) -> T where T: From> { unsafe { Radian::new( ::pact::math::atan2(y as CDouble, x as CDouble) as Self).into() } } fn cosh(arg: Self) -> Self { unsafe { ::pact::math::cosh(arg as CDouble) as Self } } fn sinh(arg: Self) -> Self { unsafe { ::pact::math::sinh(arg as CDouble) as Self } } fn tanh(arg: Self) -> Self { unsafe { ::pact::math::tanh(arg as CDouble) as Self } } fn acosh(arg: Self) -> Self { unsafe { ::pact::math::acosh(arg as CDouble) as Self } } fn asinh(arg: Self) -> Self { unsafe { ::pact::math::asinh(arg as CDouble) as Self } } fn atanh(arg: Self) -> Self { unsafe { ::pact::math::atanh(arg as CDouble) as Self } } }