2025-07-29 12:38:11 -04:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Sealed with Magistamp.
|
|
|
|
|
2017-12-17 14:32:46 -05:00
|
|
|
use binding::{CDouble, CFloat};
|
2017-06-27 18:19:33 -04:00
|
|
|
|
2019-01-20 00:59:58 -05:00
|
|
|
use crate::real::Real;
|
|
|
|
use crate::trig::radian::Radian;
|
2017-06-27 18:19:33 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// The available trigonometric functions.
|
|
|
|
pub trait Trig: Real
|
|
|
|
{
|
|
|
|
/// Computes the cosine of this angle.
|
|
|
|
///
|
|
|
|
/// ```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Radian, Trig};
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// let abs_difference: f64;
|
|
|
|
/// let radians: Radian<f64>;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// radians = Radian::new(2.0f64 * f64::PI);
|
|
|
|
/// abs_difference = (Trig::cos(radians) - 1.0f64).abs();
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
|
|
|
/// assert!(abs_difference < 1e-10);
|
|
|
|
/// ```
|
|
|
|
fn cos<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>;
|
|
|
|
|
|
|
|
/// Computes the sine of this angle.
|
|
|
|
///
|
|
|
|
/// ```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Radian, Trig};
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// let abs_difference: f64;
|
|
|
|
/// let radians: Radian<f64>;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// let radians: Radian<f64> = Radian::new(f64::PI / 2.0f64);
|
|
|
|
/// let abs_difference = (Trig::sin(radians) - 1.0f64).abs();
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
|
|
|
/// assert!(abs_difference < 1e-10);
|
|
|
|
/// ```
|
|
|
|
fn sin<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>;
|
|
|
|
|
|
|
|
/// Computes the tangent of this angle.
|
|
|
|
///
|
|
|
|
/// ```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Radian, Trig};
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// let abs_difference: f64;
|
|
|
|
/// let radians: Radian<f64>;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// radians = Radian::new(f64::PI / 4.0f64);
|
|
|
|
/// abs_difference = (Trig::tan(radians) - 1.0f64).abs();
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
|
|
|
/// assert!(abs_difference < 1e-14);
|
|
|
|
/// ```
|
|
|
|
fn tan<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>;
|
|
|
|
|
|
|
|
/// 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].
|
|
|
|
///
|
|
|
|
///```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Radian, Trig};
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// let angle: f64;
|
|
|
|
/// let radians: Radian<f64>;
|
|
|
|
/// let test: Radian<f64>;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// angle = f64::PI / 4.0f64;
|
|
|
|
/// radians = Radian::new(angle);
|
|
|
|
/// test = Trig::acos(Trig::cos(radians));
|
|
|
|
///
|
|
|
|
/// assert!((angle - *test) < 1e-10);
|
2017-06-27 18:19:33 -04:00
|
|
|
///```
|
|
|
|
fn acos<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>;
|
|
|
|
|
|
|
|
/// 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].
|
|
|
|
///
|
|
|
|
///```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Radian, Trig};
|
|
|
|
///
|
|
|
|
/// let angle: f64;
|
|
|
|
/// let radians: Radian<f64>;
|
|
|
|
/// let test: Radian<f64>;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// angle = f64::PI / 4.0f64;
|
|
|
|
/// radians = Radian::new(angle);
|
|
|
|
/// test = Trig::asin(Trig::sin(radians));
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// assert!((angle - *test) < 1e-10);
|
2017-06-27 18:19:33 -04:00
|
|
|
///```
|
|
|
|
fn asin<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>;
|
|
|
|
|
|
|
|
/// Computes the arctangent of a number. Return value is in degrees in the
|
|
|
|
/// range [-pi/2, pi/2];
|
|
|
|
///
|
|
|
|
///```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Radian, Trig};
|
|
|
|
///
|
|
|
|
/// let angle: f64;
|
|
|
|
/// let radians: Radian<f64>;
|
|
|
|
/// let test: Radian<f64>;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// angle = f64::PI / 4.0f64;
|
|
|
|
/// radians = Radian::new(angle);
|
|
|
|
/// test = Trig::atan(Trig::tan(radians));
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// assert!((angle - *test) < 1e-10);
|
2017-06-27 18:19:33 -04:00
|
|
|
///```
|
|
|
|
fn atan<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>;
|
|
|
|
|
|
|
|
/// Computes the four quadrant arctangent of y and x.
|
|
|
|
fn atan2<T>(y: Self, x: Self) -> T
|
|
|
|
where T: From<Radian<Self>>;
|
|
|
|
|
|
|
|
|
|
|
|
/// Hyperbolic cosine function.
|
|
|
|
///
|
|
|
|
/// ```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Trig};
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// let f_val: f32;
|
|
|
|
/// let g_val: f32;
|
|
|
|
/// let abs_difference: f32;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// 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();
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
|
|
|
/// // Solving cosh() at 1 gives this result
|
2017-07-01 15:32:44 -04:00
|
|
|
/// assert!(abs_difference < 1.0e-10);
|
2017-06-27 18:19:33 -04:00
|
|
|
/// ```
|
|
|
|
fn cosh(arg: Self) -> Self;
|
|
|
|
|
|
|
|
/// Hyperbolic sine function.
|
|
|
|
///
|
|
|
|
/// ```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Trig};
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// let f_val: f32;
|
|
|
|
/// let g_val: f32;
|
|
|
|
/// let abs_difference: f32;
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// 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();
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
|
|
|
/// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
|
2017-07-01 15:32:44 -04:00
|
|
|
/// assert!(abs_difference < 1e-10);
|
2017-06-27 18:19:33 -04:00
|
|
|
/// ```
|
|
|
|
fn sinh(arg: Self) -> Self;
|
|
|
|
|
|
|
|
/// Hyperbolic tangent function.
|
|
|
|
///
|
|
|
|
/// ```
|
2017-07-01 15:32:44 -04:00
|
|
|
/// use sigils::{Constants, Trig};
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
2017-07-01 15:32:44 -04:00
|
|
|
/// 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();
|
2017-06-27 18:19:33 -04:00
|
|
|
///
|
|
|
|
/// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
|
2017-07-01 15:32:44 -04:00
|
|
|
/// assert!(abs_difference < 1.0e-6);
|
2017-06-27 18:19:33 -04:00
|
|
|
/// ```
|
|
|
|
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<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::cosf(*arg.into() as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sin<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::sinf(*arg.into() as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tan<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::tanf(*arg.into() as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn acos<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(::pact::math::acosf(arg as CFloat) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn asin<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(::pact::math::asinf(arg as CFloat) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn atan<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(::pact::math::atanf(arg as CFloat) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn atan2<T>(y: Self, x: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(
|
|
|
|
::pact::math::atan2f(y as CFloat, x as CFloat) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn cosh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::coshf(arg as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sinh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::sinhf(arg as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tanh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::tanhf(arg as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn acosh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::acoshf(arg as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn asinh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::asinhf(arg as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn atanh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::atanhf(arg as CFloat) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Trig for f64
|
|
|
|
{
|
|
|
|
fn cos<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::cos(*arg.into() as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sin<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::sin(*arg.into() as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tan<T>(arg: T) -> Self
|
|
|
|
where T: Into<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::tan(*arg.into() as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn acos<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(::pact::math::acos(arg as CDouble) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn asin<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(::pact::math::asin(arg as CDouble) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn atan<T>(arg: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(::pact::math::atan(arg as CDouble) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn atan2<T>(y: Self, x: Self) -> T
|
|
|
|
where T: From<Radian<Self>>
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
Radian::new(
|
|
|
|
::pact::math::atan2(y as CDouble, x as CDouble) as Self).into()
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn cosh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::cosh(arg as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn sinh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::sinh(arg as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn tanh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::tanh(arg as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn acosh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::acosh(arg as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn asinh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::asinh(arg as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn atanh(arg: Self) -> Self
|
|
|
|
{
|
|
|
|
unsafe
|
|
|
|
{
|
2017-12-17 14:32:46 -05:00
|
|
|
::pact::math::atanh(arg as CDouble) as Self
|
2017-06-27 18:19:33 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|