Added the basic trigonometric functions.
These were moved to their own trait and removed from the definition of a Real number. This allows the definition of a trigonometric function to call a different libc trig function depending on type.
This commit is contained in:
parent
cbde731b74
commit
43a1e30808
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -1,4 +0,0 @@
|
|||||||
[root]
|
|
||||||
name = "sigils"
|
|
||||||
version = "0.1.0"
|
|
||||||
|
|
10
Cargo.toml
10
Cargo.toml
@ -1,12 +1,16 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "sigils"
|
name = "sigils"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["Jason Travis Smith <Jason@CyberMagesLLC.com>"]
|
authors = ["Jason Travis Smith <Myrddin@CyberMagesLLC.com>"]
|
||||||
description = "A mathematics library."
|
description = "A mathematics library."
|
||||||
license = ""
|
license = ""
|
||||||
repository = "https://gitlab.com/CyberMages/sigils.git"
|
repository = "https://gitlab.com/CyberMages/Core/sigils.git"
|
||||||
documentation = ""
|
documentation = ""
|
||||||
keywords = ["sigils"]
|
keywords = ["sigils"]
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies.binding]
|
||||||
|
git = "ssh://git@gitlab.com/CyberMages/Core/binding"
|
||||||
|
|
||||||
|
[dependencies.pact]
|
||||||
|
git = "ssh://git@gitlab.com/CyberMages/Core/pact"
|
||||||
|
47
examples/trig.rs
Normal file
47
examples/trig.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
extern crate pact;
|
||||||
|
extern crate sigils;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
use ::sigils::{Constants, Degree, Radian, Trig};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn main()
|
||||||
|
{
|
||||||
|
let mut val: f64;
|
||||||
|
let mut degrees: Degree<f64>;
|
||||||
|
let mut radians: Radian<f64>;
|
||||||
|
|
||||||
|
val = Constants::QUARTER_PI;
|
||||||
|
val *= 6f64;
|
||||||
|
radians = Radian::new(val);
|
||||||
|
degrees = Trig::acos(Trig::cos(radians));
|
||||||
|
|
||||||
|
println!("{:?}", radians);
|
||||||
|
println!("{:?}", degrees);
|
||||||
|
println!("");
|
||||||
|
|
||||||
|
radians = Radian::new(Constants::QUARTER_PI);
|
||||||
|
radians = Trig::acos(Trig::cos(radians));
|
||||||
|
degrees = Degree::from(radians);
|
||||||
|
|
||||||
|
println!("{:?}", radians);
|
||||||
|
println!("{:?}", degrees);
|
||||||
|
println!("");
|
||||||
|
|
||||||
|
degrees = Degree::new(270.0f64);
|
||||||
|
radians = Trig::acos(Trig::cos(degrees));
|
||||||
|
|
||||||
|
println!("{:?}", degrees);
|
||||||
|
println!("{:?}", radians);
|
||||||
|
println!("");
|
||||||
|
|
||||||
|
degrees = Degree::new(90.0f64);
|
||||||
|
degrees = Trig::acos(Trig::cos(degrees));
|
||||||
|
radians = Radian::from(degrees);
|
||||||
|
|
||||||
|
println!("{:?}", degrees);
|
||||||
|
println!("{:?}", radians);
|
||||||
|
println!("");
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
use std::{f32, f64};
|
use std::{f32, f64};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Create the Constants trait so that we can use
|
// Create the Constants trait so that we can use
|
||||||
// associated constants to define Mathematical constants for
|
// associated constants to define Mathematical constants for
|
||||||
// the f32 and f64 types.
|
// the f32 and f64 types.
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -4,6 +4,12 @@
|
|||||||
//!
|
//!
|
||||||
#![feature(float_extras)]
|
#![feature(float_extras)]
|
||||||
#![feature(associated_consts)]
|
#![feature(associated_consts)]
|
||||||
|
#![no_std]
|
||||||
|
extern crate core as std;
|
||||||
|
|
||||||
|
extern crate binding;
|
||||||
|
extern crate pact;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -19,11 +25,13 @@ mod real;
|
|||||||
mod constants;
|
mod constants;
|
||||||
|
|
||||||
mod trig;
|
mod trig;
|
||||||
|
|
||||||
pub mod vector;
|
pub mod vector;
|
||||||
pub mod matrix;
|
pub mod matrix;
|
||||||
pub mod quaternion;
|
pub mod quaternion;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub use self::zero::Zero;
|
pub use self::zero::Zero;
|
||||||
pub use self::one::One;
|
pub use self::one::One;
|
||||||
pub use self::number::Number;
|
pub use self::number::Number;
|
||||||
@ -31,4 +39,4 @@ pub use self::whole::Whole;
|
|||||||
pub use self::integer::Integer;
|
pub use self::integer::Integer;
|
||||||
pub use self::real::Real;
|
pub use self::real::Real;
|
||||||
pub use self::constants::Constants;
|
pub use self::constants::Constants;
|
||||||
pub use self::trig::{Degree, Radian};
|
pub use self::trig::{Degree, Radian, Trig};
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
macro_rules! binary_operator_impl
|
macro_rules! binary_operator_impl
|
||||||
{
|
{
|
||||||
($traitName: ident :: $funcName: ident,
|
($traitName: ident :: $funcName: ident,
|
||||||
$structName: ident {$($field: ident),+},
|
$generic_type: path $(| $generic_types2: path)*,
|
||||||
$generic_type: ident) =>
|
$structName: ident {$($field: ident),+}) =>
|
||||||
{
|
{
|
||||||
impl<T> $traitName<T> for $structName<T>
|
impl<T> $traitName<T> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<T> for &'a $structName<T>
|
impl<'a, T> $traitName<T> for &'a $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<&'a T> for $structName<T>
|
impl<'a, T> $traitName<&'a T> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -40,7 +40,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, T> $traitName<&'b T> for &'a $structName<T>
|
impl<'a, 'b, T> $traitName<&'b T> for &'a $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> $traitName<$structName<T>> for $structName<T>
|
impl<T> $traitName<$structName<T>> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<$structName<T>> for &'a $structName<T>
|
impl<'a, T> $traitName<$structName<T>> for &'a $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<&'a $structName<T>> for $structName<T>
|
impl<'a, T> $traitName<&'a $structName<T>> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, T> $traitName<&'a $structName<T>> for &'b $structName<T>
|
impl<'a, 'b, T> $traitName<&'a $structName<T>> for &'b $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -101,11 +101,11 @@ macro_rules! binary_operator_impl
|
|||||||
macro_rules! binary_operator_assign_impl
|
macro_rules! binary_operator_assign_impl
|
||||||
{
|
{
|
||||||
($traitName: ident :: $funcName: ident,
|
($traitName: ident :: $funcName: ident,
|
||||||
$structName: ident {$($field: ident),+},
|
$generic_type: path $(| $generic_types2: path)*,
|
||||||
$generic_type: ident) =>
|
$structName: ident {$($field: ident),+}) =>
|
||||||
{
|
{
|
||||||
impl<T> $traitName<$structName<T>> for $structName<T>
|
impl<T> $traitName<$structName<T>> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
fn $funcName(&mut self, rhs: $structName<T>)
|
fn $funcName(&mut self, rhs: $structName<T>)
|
||||||
{
|
{
|
||||||
@ -114,7 +114,7 @@ macro_rules! binary_operator_assign_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> $traitName<T> for $structName<T>
|
impl<T> $traitName<T> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
fn $funcName(&mut self, rhs: T)
|
fn $funcName(&mut self, rhs: T)
|
||||||
{
|
{
|
||||||
@ -123,7 +123,7 @@ macro_rules! binary_operator_assign_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<&'a $structName<T>> for $structName<T>
|
impl<'a, T> $traitName<&'a $structName<T>> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
fn $funcName(&mut self, rhs: &'a $structName<T>)
|
fn $funcName(&mut self, rhs: &'a $structName<T>)
|
||||||
{
|
{
|
||||||
@ -132,7 +132,7 @@ macro_rules! binary_operator_assign_impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<&'a T> for $structName<T>
|
impl<'a, T> $traitName<&'a T> for $structName<T>
|
||||||
where T: $generic_type
|
where T: $generic_type $(+ $generic_types2)*
|
||||||
{
|
{
|
||||||
fn $funcName(&mut self, rhs: &'a T)
|
fn $funcName(&mut self, rhs: &'a T)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,8 @@ use std::ops::{Add, Sub, Mul, Div, Neg};
|
|||||||
use ::zero::Zero;
|
use ::zero::Zero;
|
||||||
use ::one::One;
|
use ::one::One;
|
||||||
use ::real::Real;
|
use ::real::Real;
|
||||||
|
use ::trig::Radian;
|
||||||
|
use ::trig::Trig;
|
||||||
use ::vector::{Vector, EuclideanVector, Vector3};
|
use ::vector::{Vector, EuclideanVector, Vector3};
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +30,7 @@ use ::vector::{Vector, EuclideanVector, Vector3};
|
|||||||
/// | jk = 1 | kj = -1 |
|
/// | jk = 1 | kj = -1 |
|
||||||
/// | ki = 1 | ji = -1 |
|
/// | ki = 1 | ji = -1 |
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Quaternion<T> where T: Real
|
pub struct Quaternion<T>
|
||||||
{
|
{
|
||||||
/// TODO: Describe this.
|
/// TODO: Describe this.
|
||||||
pub scalar: T,
|
pub scalar: T,
|
||||||
@ -45,7 +47,7 @@ macro_rules! binary_operator_impl
|
|||||||
{
|
{
|
||||||
($traitName: ident :: $funcName: ident, $structName: ident) =>
|
($traitName: ident :: $funcName: ident, $structName: ident) =>
|
||||||
{
|
{
|
||||||
impl<T> $traitName<T> for $structName<T> where T: Real
|
impl<T> $traitName<T> for $structName<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -56,7 +58,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<T> for &'a $structName<T> where T: Real
|
impl<'a, T> $traitName<T> for &'a $structName<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -67,7 +69,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> $traitName<&'a T> for $structName<T> where T: Real
|
impl<'a, T> $traitName<&'a T> for $structName<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -78,7 +80,7 @@ macro_rules! binary_operator_impl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, T> $traitName<&'b T> for &'a $structName<T> where T: Real
|
impl<'a, 'b, T> $traitName<&'b T> for &'a $structName<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = $structName<T>;
|
type Output = $structName<T>;
|
||||||
|
|
||||||
@ -93,7 +95,7 @@ macro_rules! binary_operator_impl
|
|||||||
|
|
||||||
|
|
||||||
// Implement the Quaternion's methods.
|
// Implement the Quaternion's methods.
|
||||||
impl<T> Quaternion<T> where T: Real
|
impl<T> Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
/// Create a new Quaternion from a given scalar and Vector.
|
/// Create a new Quaternion from a given scalar and Vector.
|
||||||
///
|
///
|
||||||
@ -277,7 +279,7 @@ impl<T> Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement the Debug trait for the Quaternion.
|
// Implement the Debug trait for the Quaternion.
|
||||||
impl<T> Debug for Quaternion<T> where T: Real
|
impl<T> Debug for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error>
|
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error>
|
||||||
{
|
{
|
||||||
@ -286,7 +288,7 @@ impl<T> Debug for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement the Display trait for the Quaternion.
|
// Implement the Display trait for the Quaternion.
|
||||||
impl<T> Display for Quaternion<T> where T: Real
|
impl<T> Display for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error>
|
fn fmt(&self, formatter: &mut Formatter) -> Result<(), Error>
|
||||||
{
|
{
|
||||||
@ -296,7 +298,7 @@ impl<T> Display for Quaternion<T> where T: Real
|
|||||||
|
|
||||||
// Implement a default value for Quaternions which
|
// Implement a default value for Quaternions which
|
||||||
// returns the identity quaternion.
|
// returns the identity quaternion.
|
||||||
impl<T> Default for Quaternion<T> where T: Real
|
impl<T> Default for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn default() -> Quaternion<T>
|
fn default() -> Quaternion<T>
|
||||||
{
|
{
|
||||||
@ -305,7 +307,7 @@ impl<T> Default for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement the Zero and One traits for the Quaternion.
|
// Implement the Zero and One traits for the Quaternion.
|
||||||
impl<T> Zero for Quaternion<T> where T: Real
|
impl<T> Zero for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn zero() -> Quaternion<T>
|
fn zero() -> Quaternion<T>
|
||||||
{
|
{
|
||||||
@ -313,7 +315,7 @@ impl<T> Zero for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> One for Quaternion<T> where T: Real
|
impl<T> One for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn one() -> Quaternion<T>
|
fn one() -> Quaternion<T>
|
||||||
{
|
{
|
||||||
@ -327,7 +329,7 @@ binary_operator_impl!(Mul::mul, Quaternion);
|
|||||||
//binary_operator_impl!(Neg::neg, Quaternion);
|
//binary_operator_impl!(Neg::neg, Quaternion);
|
||||||
|
|
||||||
// Implement Negating a Quaternion.
|
// Implement Negating a Quaternion.
|
||||||
impl<T> Neg for Quaternion<T> where T: Real
|
impl<T> Neg for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -337,7 +339,7 @@ impl<T> Neg for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Neg for &'a Quaternion<T> where T: Real
|
impl<'a, T> Neg for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -348,7 +350,7 @@ impl<'a, T> Neg for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement Adding Quaternions.
|
// Implement Adding Quaternions.
|
||||||
impl<T> Add<Quaternion<T>> for Quaternion<T> where T: Real
|
impl<T> Add<Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -359,7 +361,7 @@ impl<T> Add<Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Add<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, T> Add<Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -370,7 +372,7 @@ impl<'a, T> Add<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Add<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
impl<'a, T> Add<&'a Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -381,7 +383,7 @@ impl<'a, T> Add<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, T> Add<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, 'b, T> Add<&'b Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -393,7 +395,7 @@ impl<'a, 'b, T> Add<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement subtracting Quaternions.
|
// Implement subtracting Quaternions.
|
||||||
impl<T> Sub<Quaternion<T>> for Quaternion<T> where T: Real
|
impl<T> Sub<Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -404,7 +406,7 @@ impl<T> Sub<Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Sub<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, T> Sub<Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -415,7 +417,7 @@ impl<'a, T> Sub<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Sub<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
impl<'a, T> Sub<&'a Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -426,7 +428,7 @@ impl<'a, T> Sub<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, T> Sub<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, 'b, T> Sub<&'b Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -438,7 +440,7 @@ impl<'a, 'b, T> Sub<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement Dividing Quaternions.
|
// Implement Dividing Quaternions.
|
||||||
impl<T> Div<Quaternion<T>> for Quaternion<T> where T: Real
|
impl<T> Div<Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -448,7 +450,7 @@ impl<T> Div<Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Div<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, T> Div<Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -458,7 +460,7 @@ impl<'a, T> Div<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Div<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
impl<'a, T> Div<&'a Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -468,7 +470,7 @@ impl<'a, T> Div<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, T> Div<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, 'b, T> Div<&'b Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -479,7 +481,7 @@ impl<'a, 'b, T> Div<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement multiplying Quaternions and Vectors.
|
// Implement multiplying Quaternions and Vectors.
|
||||||
impl<T> Mul<Quaternion<T>> for Quaternion<T> where T: Real
|
impl<T> Mul<Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -492,7 +494,7 @@ impl<T> Mul<Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Mul<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, T> Mul<Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -505,7 +507,7 @@ impl<'a, T> Mul<Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Mul<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
impl<'a, T> Mul<&'a Quaternion<T>> for Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -518,7 +520,7 @@ impl<'a, T> Mul<&'a Quaternion<T>> for Quaternion<T> where T: Real
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'b, T> Mul<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
impl<'a, 'b, T> Mul<&'b Quaternion<T>> for &'a Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
type Output = Quaternion<T>;
|
type Output = Quaternion<T>;
|
||||||
|
|
||||||
@ -547,7 +549,7 @@ impl<'a, 'b, T> Mul<&'b Quaternion<T>> for &'a Quaternion<T> where T: Real
|
|||||||
/// (SaZb + XaYb - YaXb + SbZa)k
|
/// (SaZb + XaYb - YaXb + SbZa)k
|
||||||
fn multiply_quaternions<T>(sa: T, xa: T, ya: T, za: T,
|
fn multiply_quaternions<T>(sa: T, xa: T, ya: T, za: T,
|
||||||
sb: T, xb: T, yb: T, zb: T)
|
sb: T, xb: T, yb: T, zb: T)
|
||||||
-> Quaternion<T> where T: Real
|
-> Quaternion<T> where T: Trig
|
||||||
{
|
{
|
||||||
let i: T;
|
let i: T;
|
||||||
let j: T;
|
let j: T;
|
||||||
|
313
src/real.rs
313
src/real.rs
@ -1,8 +1,9 @@
|
|||||||
use std::num::FpCategory;
|
use std::num::FpCategory;
|
||||||
use std::ops::Neg;
|
use std::ops::Neg;
|
||||||
|
|
||||||
|
use ::constants::Constants;
|
||||||
use ::number::Number;
|
use ::number::Number;
|
||||||
use ::trig::Radian;
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: Double check these examples. Most are OK,
|
// TODO: Double check these examples. Most are OK,
|
||||||
@ -19,7 +20,7 @@ use ::trig::Radian;
|
|||||||
/// [2]: https://doc.rust-lang.org/std/primitive.f32.html
|
/// [2]: https://doc.rust-lang.org/std/primitive.f32.html
|
||||||
/// [3]: https://doc.rust-lang.org/std/primitive.f64.html
|
/// [3]: https://doc.rust-lang.org/std/primitive.f64.html
|
||||||
/// [4]: https://doc.rust-lang.org/std/index.html
|
/// [4]: https://doc.rust-lang.org/std/index.html
|
||||||
pub trait Real : Number + Neg<Output=Self>
|
pub trait Real : Number + Constants + Neg<Output=Self>
|
||||||
{
|
{
|
||||||
/// Returns the `NaN` value.
|
/// Returns the `NaN` value.
|
||||||
///
|
///
|
||||||
@ -675,143 +676,6 @@ pub trait Real : Number + Neg<Output=Self>
|
|||||||
/// ```
|
/// ```
|
||||||
fn cbrt(self) -> Self;
|
fn cbrt(self) -> Self;
|
||||||
|
|
||||||
/// Computes the sine of a number (in radians).
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x = f64::consts::PI/2.0;
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.sin() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn sin(self) -> Self;
|
|
||||||
|
|
||||||
/// Computes the cosine of a number (in radians).
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x = 2.0*f64::consts::PI;
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.cos() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn cos(self) -> Self;
|
|
||||||
|
|
||||||
/// Computes the tangent of a number (in radians).
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x = f64::consts::PI/4.0;
|
|
||||||
/// let abs_difference = (x.tan() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-14);
|
|
||||||
/// ```
|
|
||||||
fn tan(self) -> Self;
|
|
||||||
|
|
||||||
/// Computes the arcsine of a number. Return value is in radians in
|
|
||||||
/// the range [-pi/2, pi/2] or NaN if the number is outside the range
|
|
||||||
/// [-1, 1].
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let f = f64::consts::PI / 2.0;
|
|
||||||
///
|
|
||||||
/// // asin(sin(pi/2))
|
|
||||||
/// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn asin(self) -> Radian<Self>;
|
|
||||||
|
|
||||||
/// Computes the arccosine of a number. Return value is in radians in
|
|
||||||
/// the range [0, pi] or NaN if the number is outside the range
|
|
||||||
/// [-1, 1].
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let f = f64::consts::PI / 4.0;
|
|
||||||
///
|
|
||||||
/// // acos(cos(pi/4))
|
|
||||||
/// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn acos(self) -> Radian<Self>;
|
|
||||||
|
|
||||||
/// Computes the arctangent of a number. Return value is in radians in the
|
|
||||||
/// range [-pi/2, pi/2];
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
///
|
|
||||||
/// let f = 1.0;
|
|
||||||
///
|
|
||||||
/// // atan(tan(1))
|
|
||||||
/// let abs_difference = (f.tan().atan() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn atan(self) -> Radian<Self>;
|
|
||||||
|
|
||||||
/// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
|
|
||||||
///
|
|
||||||
/// * `x = 0`, `y = 0`: `0`
|
|
||||||
/// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
|
|
||||||
/// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
|
|
||||||
/// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let pi = f64::consts::PI;
|
|
||||||
/// // All angles from horizontal right (+x)
|
|
||||||
/// // 45 deg counter-clockwise
|
|
||||||
/// let x1 = 3.0;
|
|
||||||
/// let y1 = -3.0;
|
|
||||||
///
|
|
||||||
/// // 135 deg clockwise
|
|
||||||
/// let x2 = -3.0;
|
|
||||||
/// let y2 = 3.0;
|
|
||||||
///
|
|
||||||
/// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
|
|
||||||
/// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference_1 < 1e-10);
|
|
||||||
/// assert!(abs_difference_2 < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn atan2(self, other: Self) -> Radian<Self>;
|
|
||||||
|
|
||||||
/// Simultaneously computes the sine and cosine of the number, `x`. Returns
|
|
||||||
/// `(sin(x), cos(x))`.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x = f64::consts::PI/4.0;
|
|
||||||
/// let f = x.sin_cos();
|
|
||||||
///
|
|
||||||
/// let abs_difference_0 = (f.0 - x.sin()).abs();
|
|
||||||
/// let abs_difference_1 = (f.1 - x.cos()).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference_0 < 1e-10);
|
|
||||||
/// assert!(abs_difference_0 < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn sin_cos(self) -> (Self, Self);
|
|
||||||
|
|
||||||
/// Returns `e^(self) - 1` in a way that is accurate even if the
|
/// Returns `e^(self) - 1` in a way that is accurate even if the
|
||||||
/// number is close to zero.
|
/// number is close to zero.
|
||||||
///
|
///
|
||||||
@ -847,133 +711,10 @@ pub trait Real : Number + Neg<Output=Self>
|
|||||||
/// assert!(abs_difference64 < 1e-10);
|
/// assert!(abs_difference64 < 1e-10);
|
||||||
/// ```
|
/// ```
|
||||||
fn ln_1p(self) -> Self;
|
fn ln_1p(self) -> Self;
|
||||||
|
|
||||||
/// Hyperbolic sine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: f32 = 1.0f32;
|
|
||||||
///
|
|
||||||
/// let f_val32 = x32.sinh();
|
|
||||||
/// let g_val32 = (e32*e32 - 1.0f32)/(2.0f32*e32);
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: f64 = 1.0f64;
|
|
||||||
///
|
|
||||||
/// let f_val64 = x64.sinh();
|
|
||||||
/// let g_val64 = (e64*e64 - 1.0f64)/(2.0f64*e64);
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
|
|
||||||
/// //assert!(abs_difference32 < 1e-10);
|
|
||||||
/// assert!(abs_difference64 < 1e-10);
|
|
||||||
/// ```
|
|
||||||
fn sinh(self) -> Self;
|
|
||||||
|
|
||||||
/// Hyperbolic cosine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: f32 = 1.0f32;
|
|
||||||
/// let f_val32 = x32.cosh();
|
|
||||||
/// let g_val32 = (e32*e32 + 1.0f32)/(2.0f32*e32);
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: f64 = 1.0f64;
|
|
||||||
/// let f_val64 = x64.cosh();
|
|
||||||
/// let g_val64 = (e64*e64 + 1.0f64)/(2.0f64*e64);
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving cosh() at 1 gives this result
|
|
||||||
/// //assert!(abs_difference32 < 1.0e-10);
|
|
||||||
/// assert!(abs_difference64 < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
fn cosh(self) -> Self;
|
|
||||||
|
|
||||||
/// Hyperbolic tangent function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: f32 = 1.0f32;
|
|
||||||
///
|
|
||||||
/// let f_val32 = x32.tanh();
|
|
||||||
/// let g_val32 = (1.0f32 - e32.powi(-2i32))/(1.0f32 + e32.powi(-2i32));
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: f64 = 1.0f64;
|
|
||||||
///
|
|
||||||
/// let f_val64 = x64.tanh();
|
|
||||||
/// let g_val64 = (1.0f64 - e64.powi(-2i32))/(1.0f64 + e64.powi(-2i32));
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
|
|
||||||
/// //assert!(abs_difference32 < 1.0e-10);
|
|
||||||
/// assert!(abs_difference64 < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
fn tanh(self) -> Self;
|
|
||||||
|
|
||||||
/// Inverse hyperbolic sine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
///
|
|
||||||
/// let x = 1.0;
|
|
||||||
/// let f = x.sinh().asinh();
|
|
||||||
///
|
|
||||||
/// let abs_difference = (f - x).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
fn asinh(self) -> Radian<Self>;
|
|
||||||
|
|
||||||
/// Inverse hyperbolic cosine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
///
|
|
||||||
/// let x = 1.0;
|
|
||||||
/// let f = x.cosh().acosh();
|
|
||||||
///
|
|
||||||
/// let abs_difference = (f - x).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
fn acosh(self) -> Radian<Self>;
|
|
||||||
|
|
||||||
/// Inverse hyperbolic tangent function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Real;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let f_val32 = e32.tanh().atanh();
|
|
||||||
/// let abs_difference32 = (f_val32 - e32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let f_val64 = e64.tanh().atanh();
|
|
||||||
/// let abs_difference64 = (f_val64 - e64).abs();
|
|
||||||
///
|
|
||||||
/// //assert!(abs_difference32 < 1.0e-10);
|
|
||||||
/// assert!(abs_difference64 < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
fn atanh(self) -> Radian<Self>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create a macro to ease typing and reading.
|
// Create some macros to ease typing and reading.
|
||||||
///
|
///
|
||||||
macro_rules! define_self_func
|
macro_rules! define_self_func
|
||||||
{
|
{
|
||||||
@ -998,18 +739,6 @@ macro_rules! define_self_bool_func
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
macro_rules! define_self_rad_func
|
|
||||||
{
|
|
||||||
($varType: ident, $funcName: ident) =>
|
|
||||||
{
|
|
||||||
fn $funcName(self) -> Radian<$varType>
|
|
||||||
{
|
|
||||||
Radian::new(<$varType>::$funcName(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
///
|
||||||
macro_rules! define_self_other_func
|
macro_rules! define_self_other_func
|
||||||
{
|
{
|
||||||
@ -1022,18 +751,6 @@ macro_rules! define_self_other_func
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
|
||||||
macro_rules! define_self_other_rad_func
|
|
||||||
{
|
|
||||||
($varType: ident, $funcName: ident) =>
|
|
||||||
{
|
|
||||||
fn $funcName(self, other: $varType) -> Radian<$varType>
|
|
||||||
{
|
|
||||||
Radian::new(<$varType>::$funcName(self, other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A macro to make implementing the trait easier for all the
|
/// A macro to make implementing the trait easier for all the
|
||||||
/// base float types in rust.
|
/// base float types in rust.
|
||||||
macro_rules! real_trait_impl
|
macro_rules! real_trait_impl
|
||||||
@ -1082,11 +799,6 @@ macro_rules! real_trait_impl
|
|||||||
<$varType>::powf(self, n)
|
<$varType>::powf(self, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sin_cos(self) -> ($varType, $varType)
|
|
||||||
{
|
|
||||||
<$varType>::sin_cos(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
define_self_bool_func!($varType, is_nan);
|
define_self_bool_func!($varType, is_nan);
|
||||||
define_self_bool_func!($varType, is_infinite);
|
define_self_bool_func!($varType, is_infinite);
|
||||||
define_self_bool_func!($varType, is_finite);
|
define_self_bool_func!($varType, is_finite);
|
||||||
@ -1118,24 +830,11 @@ macro_rules! real_trait_impl
|
|||||||
define_self_other_func!($varType, log);
|
define_self_other_func!($varType, log);
|
||||||
define_self_func!($varType, log2);
|
define_self_func!($varType, log2);
|
||||||
define_self_func!($varType, log10);
|
define_self_func!($varType, log10);
|
||||||
|
|
||||||
define_self_func!($varType, cos);
|
|
||||||
define_self_func!($varType, sin);
|
|
||||||
define_self_func!($varType, tan);
|
|
||||||
define_self_rad_func!($varType, acos);
|
|
||||||
define_self_rad_func!($varType, asin);
|
|
||||||
define_self_rad_func!($varType, atan);
|
|
||||||
define_self_func!($varType, cosh);
|
|
||||||
define_self_func!($varType, sinh);
|
|
||||||
define_self_func!($varType, tanh);
|
|
||||||
define_self_rad_func!($varType, acosh);
|
|
||||||
define_self_rad_func!($varType, asinh);
|
|
||||||
define_self_rad_func!($varType, atanh);
|
|
||||||
define_self_other_rad_func!($varType, atan2);
|
|
||||||
}
|
}
|
||||||
)*)
|
)*)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Implement the trait for the types that are Real numbers.
|
// Implement the trait for the types that are Real numbers.
|
||||||
real_trait_impl!(Real for f32 f64);
|
real_trait_impl!(Real for f32);
|
||||||
|
real_trait_impl!(Real for f64);
|
||||||
|
716
src/trig.rs
716
src/trig.rs
@ -1,716 +0,0 @@
|
|||||||
use std::ops::{Add, Sub, Mul, Div, Rem, Neg};
|
|
||||||
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
|
||||||
|
|
||||||
use ::constants::Constants;
|
|
||||||
use ::real::Real;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// A degree usually denoted by ° (the degree symbol),
|
|
||||||
/// is a measurement of a plane angle, defined so that a
|
|
||||||
/// full rotation is 360 degrees.
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
|
|
||||||
pub struct Degree<T>
|
|
||||||
{
|
|
||||||
value: T
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A unit of angle, equal to an angle at the center of
|
|
||||||
/// a circle whose arc is equal in length to the radius.
|
|
||||||
#[derive(Clone, Copy, Eq, PartialEq, Hash)]
|
|
||||||
pub struct Radian<T>
|
|
||||||
{
|
|
||||||
value: T
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl<T> Degree<T> where T: Real
|
|
||||||
{
|
|
||||||
/// Create a new Degree structure with the given value.
|
|
||||||
pub fn new(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
Degree
|
|
||||||
{
|
|
||||||
value: val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the arccosine of a number. Return value is in Degrees in
|
|
||||||
/// the range [0, 180] or NaN if the number is outside the range
|
|
||||||
/// [-1, 1].
|
|
||||||
///
|
|
||||||
///```
|
|
||||||
/// use sigils::{Degree, Real};
|
|
||||||
///
|
|
||||||
/// let f: Degree<f64>;
|
|
||||||
///
|
|
||||||
/// f = Degree::from(45.0f64);
|
|
||||||
/// assert!((45.0f64 - *Degree::acos(f.cos())) < 1e-10);
|
|
||||||
///```
|
|
||||||
pub fn acos(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = val.acos();
|
|
||||||
Degree::from(radians)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the arcsine of a number. Return value is in Degrees in
|
|
||||||
/// the range [-57.2957795/2, 57.2957795/2] or NaN if the number is
|
|
||||||
/// outside the range [-1, 1].
|
|
||||||
///
|
|
||||||
///```
|
|
||||||
/// use sigils::{Degree, Real};
|
|
||||||
///
|
|
||||||
/// let f: Degree<f64>;
|
|
||||||
///
|
|
||||||
/// f = Degree::from(45.0f64);
|
|
||||||
/// assert!((45.0f64 - *Degree::asin(f.sin())) < 1e-10);
|
|
||||||
///```
|
|
||||||
pub fn asin(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = val.asin();
|
|
||||||
Degree::from(radians)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the arctangent of a number. Return value is in degrees in the
|
|
||||||
/// range [-57.2957795/2, 57.2957795/2];
|
|
||||||
///
|
|
||||||
///```
|
|
||||||
/// use sigils::{Degree, Real};
|
|
||||||
///
|
|
||||||
/// let f: Degree<f64>;
|
|
||||||
///
|
|
||||||
/// f = Degree::from(45.0f64);
|
|
||||||
/// assert!((45.0f64 - *Degree::atan(f.tan())) < 1e-10);
|
|
||||||
///```
|
|
||||||
pub fn atan(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = val.atan();
|
|
||||||
Degree::from(radians)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inverse hyperbolic cosine function.
|
|
||||||
pub fn acosh(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = val.acosh();
|
|
||||||
Degree::from(radians)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inverse hyperbolic sine function.
|
|
||||||
pub fn asinh(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = val.asinh();
|
|
||||||
Degree::from(radians)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inverse hyperbolic tangent function.
|
|
||||||
pub fn atanh(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = val.atanh();
|
|
||||||
Degree::from(radians)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
|
|
||||||
pub fn atan2(y: T, x: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = y.atan2(x);
|
|
||||||
Degree::from(radians)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the cosine of this angle.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Degree;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x: Degree<f64> = Degree::from(360.0f64);
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.cos() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn cos(&self) -> T
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = Radian::from(*self);
|
|
||||||
radians.cos()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the sine of this angle.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Degree;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x: Degree<f64> = Degree::from(90.0f64);
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.sin() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn sin(&self) -> T
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = Radian::from(*self);
|
|
||||||
radians.sin()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the tangent of this angle.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Degree;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x: Degree<f64> = Degree::from(45.0f64);
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.tan() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-14);
|
|
||||||
/// ```
|
|
||||||
pub fn tan(&self) -> T
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = Radian::from(*self);
|
|
||||||
radians.tan()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hyperbolic cosine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Degree;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: Degree<f32> = Degree::from(f32::INVERSE_PI_DIVIDED_BY_180);
|
|
||||||
/// let f_val32 = x32.cosh();
|
|
||||||
/// let g_val32 = (e32*e32 + 1.0f32)/(2.0f32*e32);
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: Degree<f64> = Degree::from(f64::INVERSE_PI_DIVIDED_BY_180);
|
|
||||||
/// let f_val64 = x64.cosh();
|
|
||||||
/// let g_val64 = (e64*e64 + 1.0f64)/(2.0f64*e64);
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving cosh() at 1 gives this result
|
|
||||||
/// //assert!(abs_difference32 < 1.0e-10);
|
|
||||||
/// assert!(abs_difference64 < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn cosh(&self) -> T
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = Radian::from(*self);
|
|
||||||
radians.cosh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hyperbolic sine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Degree;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: Degree<f32> = Degree::from(f32::INVERSE_PI_DIVIDED_BY_180);
|
|
||||||
///
|
|
||||||
/// let f_val32 = x32.sinh();
|
|
||||||
/// let g_val32 = (e32*e32 - 1.0f32)/(2.0f32*e32);
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: Degree<f64> = Degree::from(f64::INVERSE_PI_DIVIDED_BY_180);
|
|
||||||
///
|
|
||||||
/// let f_val64 = x64.sinh();
|
|
||||||
/// let g_val64 = (e64*e64 - 1.0f64)/(2.0f64*e64);
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
|
|
||||||
/// //assert!(abs_difference32 < 1e-10);
|
|
||||||
/// assert!(abs_difference64 < 1e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn sinh(&self) -> T
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = Radian::from(*self);
|
|
||||||
radians.sinh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hyperbolic tangent function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Degree;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: Degree<f32> = Degree::from(f32::INVERSE_PI_DIVIDED_BY_180);
|
|
||||||
///
|
|
||||||
/// let f_val32 = x32.tanh();
|
|
||||||
/// let g_val32 = (1.0f32 - e32.powi(-2i32))/(1.0f32 + e32.powi(-2i32));
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: Degree<f64> = Degree::from(f64::INVERSE_PI_DIVIDED_BY_180);
|
|
||||||
///
|
|
||||||
/// let f_val64 = x64.tanh();
|
|
||||||
/// let g_val64 = (1.0f64 - e64.powi(-2i32))/(1.0f64 + e64.powi(-2i32));
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
|
|
||||||
/// //assert!(abs_difference32 < 1.0e-10);
|
|
||||||
/// assert!(abs_difference64 < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn tanh(&self) -> T
|
|
||||||
{
|
|
||||||
let radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = Radian::from(*self);
|
|
||||||
radians.tanh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::ops::Deref for Degree<T> where T: Real
|
|
||||||
{
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &T
|
|
||||||
{
|
|
||||||
&self.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::ops::DerefMut for Degree<T> where T: Real
|
|
||||||
{
|
|
||||||
fn deref_mut<'a>(&'a mut self) -> &'a mut T
|
|
||||||
{
|
|
||||||
&mut self.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binary_operator_impl!(Add::add, Degree {value}, Real);
|
|
||||||
binary_operator_impl!(Sub::sub, Degree {value}, Real);
|
|
||||||
binary_operator_impl!(Mul::mul, Degree {value}, Real);
|
|
||||||
binary_operator_impl!(Div::div, Degree {value}, Real);
|
|
||||||
binary_operator_impl!(Rem::rem, Degree {value}, Real);
|
|
||||||
|
|
||||||
impl<T> ::std::ops::Neg for Degree<T>
|
|
||||||
where T: Neg<Output = T>
|
|
||||||
{
|
|
||||||
type Output = Degree<T>;
|
|
||||||
|
|
||||||
fn neg(self) -> Degree<T>
|
|
||||||
{
|
|
||||||
let mut degrees: Degree<T>;
|
|
||||||
|
|
||||||
degrees = self;
|
|
||||||
degrees.value = degrees.value.neg();
|
|
||||||
degrees
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binary_operator_assign_impl!(AddAssign::add_assign,
|
|
||||||
Degree {value}, Real);
|
|
||||||
binary_operator_assign_impl!(SubAssign::sub_assign,
|
|
||||||
Degree {value}, Real);
|
|
||||||
binary_operator_assign_impl!(MulAssign::mul_assign,
|
|
||||||
Degree {value}, Real);
|
|
||||||
binary_operator_assign_impl!(DivAssign::div_assign,
|
|
||||||
Degree {value}, Real);
|
|
||||||
binary_operator_assign_impl!(RemAssign::rem_assign,
|
|
||||||
Degree {value}, Real);
|
|
||||||
|
|
||||||
impl ::std::convert::From<Degree<f32>> for f32
|
|
||||||
{
|
|
||||||
fn from(degrees: Degree<f32>) -> f32
|
|
||||||
{
|
|
||||||
degrees.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::convert::From<Degree<f64>> for f64
|
|
||||||
{
|
|
||||||
fn from(degrees: Degree<f64>) -> f64
|
|
||||||
{
|
|
||||||
degrees.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::convert::From<T> for Degree<T> where T: Real
|
|
||||||
{
|
|
||||||
fn from(val: T) -> Degree<T>
|
|
||||||
{
|
|
||||||
Degree::new(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::convert::From<Radian<T>> for Degree<T> where T: Real
|
|
||||||
{
|
|
||||||
fn from(radians: Radian<T>) -> Degree<T>
|
|
||||||
{
|
|
||||||
let degs: T;
|
|
||||||
|
|
||||||
degs = radians.value * Constants::INVERSE_PI_DIVIDED_BY_180;
|
|
||||||
Degree::new(degs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::fmt::Debug for Degree<T>
|
|
||||||
where T: Real
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
|
||||||
{
|
|
||||||
::std::fmt::Display::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::fmt::Display for Degree<T>
|
|
||||||
where T: Real
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
|
||||||
{
|
|
||||||
write!(f, "{}", self.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Radian<T> where T: Real
|
|
||||||
{
|
|
||||||
/// Create a new Radian structure with the given value.
|
|
||||||
pub fn new(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
Radian
|
|
||||||
{
|
|
||||||
value: val
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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, Real};
|
|
||||||
///
|
|
||||||
/// let f: Radian<f64>;
|
|
||||||
///
|
|
||||||
/// f = Radian::from(f64::PI / 4.0f64);
|
|
||||||
/// assert!(((f64::PI / 4.0f64) - *Radian::acos(f.cos())) < 1e-10);
|
|
||||||
///```
|
|
||||||
pub fn acos(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
val.acos()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 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, Real};
|
|
||||||
///
|
|
||||||
/// let f: Radian<f64>;
|
|
||||||
///
|
|
||||||
/// f = Radian::from(f64::PI / 4.0f64);
|
|
||||||
/// assert!(((f64::PI / 4.0f64) - *Radian::asin(f.sin())) < 1e-10);
|
|
||||||
///```
|
|
||||||
pub fn asin(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
val.asin()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the arctangent of a number. Return value is in degrees in the
|
|
||||||
/// range [-pi/2, pi/2];
|
|
||||||
///
|
|
||||||
///```
|
|
||||||
/// use sigils::{Constants, Radian, Real};
|
|
||||||
///
|
|
||||||
/// let f: Radian<f64>;
|
|
||||||
///
|
|
||||||
/// f = Radian::from(f64::PI / 4.0f64);
|
|
||||||
/// assert!(((f64::PI / 4.0f64) - *Radian::atan(f.tan())) < 1e-10);
|
|
||||||
///```
|
|
||||||
pub fn atan(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
val.atan()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inverse hyperbolic cosine function.
|
|
||||||
pub fn acosh(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
val.acosh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inverse hyperbolic sine function.
|
|
||||||
pub fn asinh(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
val.asinh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inverse hyperbolic tangent function.
|
|
||||||
pub fn atanh(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
val.atanh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`).
|
|
||||||
pub fn atan2(y: T, x: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
y.atan2(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the cosine of this angle.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Radian;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x: Radian<f64> = Radian::from(2.0*f64::consts::PI);
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.cos() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn cos(&self) -> T
|
|
||||||
{
|
|
||||||
self.value.cos()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the sine of this angle.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Radian;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x: Radian<f64> = Radian::from(f64::consts::PI/2.0);
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.sin() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn sin(&self) -> T
|
|
||||||
{
|
|
||||||
self.value.sin()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Computes the tangent of this angle.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Radian;
|
|
||||||
/// use std::f64;
|
|
||||||
///
|
|
||||||
/// let x: Radian<f64> = Radian::from(f64::consts::PI/4.0);
|
|
||||||
///
|
|
||||||
/// let abs_difference = (x.tan() - 1.0).abs();
|
|
||||||
///
|
|
||||||
/// assert!(abs_difference < 1e-14);
|
|
||||||
/// ```
|
|
||||||
pub fn tan(&self) -> T
|
|
||||||
{
|
|
||||||
self.value.tan()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hyperbolic cosine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Radian;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: Radian<f32> = Radian::new(1.0f32);
|
|
||||||
/// let f_val32 = x32.cosh();
|
|
||||||
/// let g_val32 = (e32*e32 + 1.0f32)/(2.0f32*e32);
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: Radian<f64> = Radian::new(1.0f64);
|
|
||||||
/// let f_val64 = x64.cosh();
|
|
||||||
/// let g_val64 = (e64*e64 + 1.0f64)/(2.0f64*e64);
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving cosh() at 1 gives this result
|
|
||||||
/// //assert!(abs_difference32 < 1.0e-10);
|
|
||||||
/// assert!(abs_difference64 < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn cosh(&self) -> T
|
|
||||||
{
|
|
||||||
self.value.cosh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hyperbolic sine function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Radian;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: Radian<f32> = Radian::from(1.0f32);
|
|
||||||
///
|
|
||||||
/// let f_val32 = x32.sinh();
|
|
||||||
/// let g_val32 = (e32*e32 - 1.0f32)/(2.0f32*e32);
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: Radian<f64> = Radian::from(1.0f64);
|
|
||||||
///
|
|
||||||
/// let f_val64 = x64.sinh();
|
|
||||||
/// let g_val64 = (e64*e64 - 1.0f64)/(2.0f64*e64);
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
|
|
||||||
/// //assert!(abs_difference32 < 1e-10);
|
|
||||||
/// assert!(abs_difference64 < 1e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn sinh(&self) -> T
|
|
||||||
{
|
|
||||||
self.value.sinh()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Hyperbolic tangent function.
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use sigils::Radian;
|
|
||||||
/// use sigils::Constants;
|
|
||||||
///
|
|
||||||
/// let e32: f32 = Constants::E;
|
|
||||||
/// let x32: Radian<f32> = Radian::from(1.0f32);
|
|
||||||
///
|
|
||||||
/// let f_val32 = x32.tanh();
|
|
||||||
/// let g_val32 = (1.0f32 - e32.powi(-2i32))/(1.0f32 + e32.powi(-2i32));
|
|
||||||
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
|
||||||
///
|
|
||||||
/// let e64: f64 = Constants::E;
|
|
||||||
/// let x64: Radian<f64> = Radian::from(1.0f64);
|
|
||||||
///
|
|
||||||
/// let f_val64 = x64.tanh();
|
|
||||||
/// let g_val64 = (1.0f64 - e64.powi(-2i32))/(1.0f64 + e64.powi(-2i32));
|
|
||||||
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
|
||||||
///
|
|
||||||
/// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
|
|
||||||
/// //assert!(abs_difference32 < 1.0e-10);
|
|
||||||
/// assert!(abs_difference64 < 1.0e-10);
|
|
||||||
/// ```
|
|
||||||
pub fn tanh(&self) -> T
|
|
||||||
{
|
|
||||||
self.value.tanh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::ops::Deref for Radian<T> where T: Real
|
|
||||||
{
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &T
|
|
||||||
{
|
|
||||||
&self.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::ops::DerefMut for Radian<T> where T: Real
|
|
||||||
{
|
|
||||||
fn deref_mut<'a>(&'a mut self) -> &'a mut T
|
|
||||||
{
|
|
||||||
&mut self.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binary_operator_impl!(Add::add, Radian {value}, Real);
|
|
||||||
binary_operator_impl!(Sub::sub, Radian {value}, Real);
|
|
||||||
binary_operator_impl!(Mul::mul, Radian {value}, Real);
|
|
||||||
binary_operator_impl!(Div::div, Radian {value}, Real);
|
|
||||||
binary_operator_impl!(Rem::rem, Radian {value}, Real);
|
|
||||||
|
|
||||||
impl<T> ::std::ops::Neg for Radian<T>
|
|
||||||
where T: Neg<Output = T>
|
|
||||||
{
|
|
||||||
type Output = Radian<T>;
|
|
||||||
|
|
||||||
fn neg(self) -> Radian<T>
|
|
||||||
{
|
|
||||||
let mut radians: Radian<T>;
|
|
||||||
|
|
||||||
radians = self;
|
|
||||||
radians.value = radians.value.neg();
|
|
||||||
radians
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binary_operator_assign_impl!(AddAssign::add_assign,
|
|
||||||
Radian {value}, Real);
|
|
||||||
binary_operator_assign_impl!(SubAssign::sub_assign,
|
|
||||||
Radian {value}, Real);
|
|
||||||
binary_operator_assign_impl!(MulAssign::mul_assign,
|
|
||||||
Radian {value}, Real);
|
|
||||||
binary_operator_assign_impl!(DivAssign::div_assign,
|
|
||||||
Radian {value}, Real);
|
|
||||||
binary_operator_assign_impl!(RemAssign::rem_assign,
|
|
||||||
Radian {value}, Real);
|
|
||||||
|
|
||||||
impl ::std::convert::From<Radian<f32>> for f32
|
|
||||||
{
|
|
||||||
fn from(radians: Radian<f32>) -> f32
|
|
||||||
{
|
|
||||||
radians.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ::std::convert::From<Radian<f64>> for f64
|
|
||||||
{
|
|
||||||
fn from(radians: Radian<f64>) -> f64
|
|
||||||
{
|
|
||||||
radians.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::convert::From<T> for Radian<T> where T: Real
|
|
||||||
{
|
|
||||||
fn from(val: T) -> Radian<T>
|
|
||||||
{
|
|
||||||
Radian::new(val)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::convert::From<Degree<T>> for Radian<T>
|
|
||||||
where T: Real
|
|
||||||
{
|
|
||||||
fn from(degrees: Degree<T>) -> Radian<T>
|
|
||||||
{
|
|
||||||
let rads: T;
|
|
||||||
|
|
||||||
rads = degrees.value * Constants::PI_DIVIDED_BY_180;
|
|
||||||
Radian::new(rads)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::fmt::Debug for Radian<T>
|
|
||||||
where T: Real
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
|
||||||
{
|
|
||||||
::std::fmt::Display::fmt(self, f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> ::std::fmt::Display for Radian<T>
|
|
||||||
where T: Real
|
|
||||||
{
|
|
||||||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
|
||||||
{
|
|
||||||
write!(f, "{}", self.value)
|
|
||||||
}
|
|
||||||
}
|
|
134
src/trig/degree.rs
Normal file
134
src/trig/degree.rs
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
use std::ops::{Add, Sub, Mul, Div, Rem, Neg};
|
||||||
|
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
||||||
|
|
||||||
|
use ::constants::Constants;
|
||||||
|
use ::real::Real;
|
||||||
|
use ::trig::radian::Radian;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// A degree usually denoted by ° (the degree symbol),
|
||||||
|
/// is a measurement of a plane angle, defined so that a
|
||||||
|
/// full rotation is 360 degree.
|
||||||
|
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash)]
|
||||||
|
pub struct Degree<T>
|
||||||
|
{
|
||||||
|
value: T
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl<T> Degree<T> where T: Real
|
||||||
|
{
|
||||||
|
/// Create a new Degree structure with the given value.
|
||||||
|
pub fn new(val: T) -> Self
|
||||||
|
{
|
||||||
|
Degree
|
||||||
|
{
|
||||||
|
value: val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::ops::Deref for Degree<T> where T: Real
|
||||||
|
{
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &T
|
||||||
|
{
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::ops::DerefMut for Degree<T> where T: Real
|
||||||
|
{
|
||||||
|
fn deref_mut<'a>(&'a mut self) -> &'a mut T
|
||||||
|
{
|
||||||
|
&mut self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_operator_impl!(Add::add, Real, Degree {value});
|
||||||
|
binary_operator_impl!(Sub::sub, Real, Degree {value});
|
||||||
|
binary_operator_impl!(Mul::mul, Real, Degree {value});
|
||||||
|
binary_operator_impl!(Div::div, Real, Degree {value});
|
||||||
|
binary_operator_impl!(Rem::rem, Real, Degree {value});
|
||||||
|
|
||||||
|
impl<T> ::std::ops::Neg for Degree<T>
|
||||||
|
where T: Neg<Output = T>
|
||||||
|
{
|
||||||
|
type Output = Degree<T>;
|
||||||
|
|
||||||
|
fn neg(self) -> Degree<T>
|
||||||
|
{
|
||||||
|
let mut degree: Degree<T>;
|
||||||
|
|
||||||
|
degree = self;
|
||||||
|
degree.value = degree.value.neg();
|
||||||
|
degree
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_operator_assign_impl!(AddAssign::add_assign,
|
||||||
|
Real, Degree {value});
|
||||||
|
binary_operator_assign_impl!(SubAssign::sub_assign,
|
||||||
|
Real, Degree {value});
|
||||||
|
binary_operator_assign_impl!(MulAssign::mul_assign,
|
||||||
|
Real, Degree {value});
|
||||||
|
binary_operator_assign_impl!(DivAssign::div_assign,
|
||||||
|
Real, Degree {value});
|
||||||
|
binary_operator_assign_impl!(RemAssign::rem_assign,
|
||||||
|
Real, Degree {value});
|
||||||
|
|
||||||
|
impl ::std::convert::From<Degree<f32>> for f32
|
||||||
|
{
|
||||||
|
fn from(degree: Degree<f32>) -> f32
|
||||||
|
{
|
||||||
|
degree.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::convert::From<Degree<f64>> for f64
|
||||||
|
{
|
||||||
|
fn from(degree: Degree<f64>) -> f64
|
||||||
|
{
|
||||||
|
degree.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::convert::From<T> for Degree<T> where T: Real
|
||||||
|
{
|
||||||
|
fn from(val: T) -> Degree<T>
|
||||||
|
{
|
||||||
|
Degree::new(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::convert::From<Radian<T>> for Degree<T> where T: Real
|
||||||
|
{
|
||||||
|
fn from(radians: Radian<T>) -> Degree<T>
|
||||||
|
{
|
||||||
|
let degs: T;
|
||||||
|
|
||||||
|
degs = *radians * Constants::INVERSE_PI_DIVIDED_BY_180;
|
||||||
|
Degree::new(degs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::fmt::Debug for Degree<T>
|
||||||
|
where T: Real
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
||||||
|
{
|
||||||
|
::std::fmt::Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::fmt::Display for Degree<T>
|
||||||
|
where T: Real
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
||||||
|
{
|
||||||
|
write!(f, "Degree({})", self.value)
|
||||||
|
}
|
||||||
|
}
|
15
src/trig/mod.rs
Normal file
15
src/trig/mod.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//! This section of the library handles the branch of mathematics
|
||||||
|
//! that studies relationships involving lengths and angles of triangles.
|
||||||
|
|
||||||
|
mod degree;
|
||||||
|
//mod grad;
|
||||||
|
mod radian;
|
||||||
|
mod trig;
|
||||||
|
//mod turn;
|
||||||
|
|
||||||
|
|
||||||
|
pub use self::degree::Degree;
|
||||||
|
//pub use self::grad::Grad;
|
||||||
|
pub use self::radian::Radian;
|
||||||
|
pub use self::trig::Trig;
|
||||||
|
//pub use self::turn::Turn;
|
133
src/trig/radian.rs
Normal file
133
src/trig/radian.rs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
use std::ops::{Add, Sub, Mul, Div, Rem, Neg};
|
||||||
|
use std::ops::{AddAssign, SubAssign, MulAssign, DivAssign, RemAssign};
|
||||||
|
|
||||||
|
use ::constants::Constants;
|
||||||
|
use ::real::Real;
|
||||||
|
use ::trig::degree::Degree;
|
||||||
|
|
||||||
|
|
||||||
|
/// A unit of angle, equal to an angle at the center of
|
||||||
|
/// a circle whose arc is equal in length to the radius.
|
||||||
|
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd, Hash)]
|
||||||
|
pub struct Radian<T>
|
||||||
|
{
|
||||||
|
value: T
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl<T> Radian<T> where T: Real
|
||||||
|
{
|
||||||
|
/// Create a new Radian structure with the given value.
|
||||||
|
pub fn new(val: T) -> Self
|
||||||
|
{
|
||||||
|
Radian
|
||||||
|
{
|
||||||
|
value: val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::ops::Deref for Radian<T> where T: Real
|
||||||
|
{
|
||||||
|
type Target = T;
|
||||||
|
|
||||||
|
fn deref(&self) -> &T
|
||||||
|
{
|
||||||
|
&self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::ops::DerefMut for Radian<T> where T: Real
|
||||||
|
{
|
||||||
|
fn deref_mut<'a>(&'a mut self) -> &'a mut T
|
||||||
|
{
|
||||||
|
&mut self.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_operator_impl!(Add::add, Real, Radian {value});
|
||||||
|
binary_operator_impl!(Sub::sub, Real, Radian {value});
|
||||||
|
binary_operator_impl!(Mul::mul, Real, Radian {value});
|
||||||
|
binary_operator_impl!(Div::div, Real, Radian {value});
|
||||||
|
binary_operator_impl!(Rem::rem, Real, Radian {value});
|
||||||
|
|
||||||
|
impl<T> ::std::ops::Neg for Radian<T>
|
||||||
|
where T: Neg<Output = T>
|
||||||
|
{
|
||||||
|
type Output = Radian<T>;
|
||||||
|
|
||||||
|
fn neg(self) -> Radian<T>
|
||||||
|
{
|
||||||
|
let mut radian: Radian<T>;
|
||||||
|
|
||||||
|
radian = self;
|
||||||
|
radian.value = radian.value.neg();
|
||||||
|
radian
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binary_operator_assign_impl!(AddAssign::add_assign,
|
||||||
|
Real, Radian {value});
|
||||||
|
binary_operator_assign_impl!(SubAssign::sub_assign,
|
||||||
|
Real, Radian {value});
|
||||||
|
binary_operator_assign_impl!(MulAssign::mul_assign,
|
||||||
|
Real, Radian {value});
|
||||||
|
binary_operator_assign_impl!(DivAssign::div_assign,
|
||||||
|
Real, Radian {value});
|
||||||
|
binary_operator_assign_impl!(RemAssign::rem_assign,
|
||||||
|
Real, Radian {value});
|
||||||
|
|
||||||
|
impl ::std::convert::From<Radian<f32>> for f32
|
||||||
|
{
|
||||||
|
fn from(radian: Radian<f32>) -> f32
|
||||||
|
{
|
||||||
|
radian.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ::std::convert::From<Radian<f64>> for f64
|
||||||
|
{
|
||||||
|
fn from(radian: Radian<f64>) -> f64
|
||||||
|
{
|
||||||
|
radian.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::convert::From<T> for Radian<T> where T: Real
|
||||||
|
{
|
||||||
|
fn from(val: T) -> Radian<T>
|
||||||
|
{
|
||||||
|
Radian::new(val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::convert::From<Degree<T>> for Radian<T>
|
||||||
|
where T: Real
|
||||||
|
{
|
||||||
|
fn from(degrees: Degree<T>) -> Radian<T>
|
||||||
|
{
|
||||||
|
let rads: T;
|
||||||
|
|
||||||
|
rads = *degrees * Constants::PI_DIVIDED_BY_180;
|
||||||
|
Radian::new(rads)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::fmt::Debug for Radian<T>
|
||||||
|
where T: Real
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
||||||
|
{
|
||||||
|
::std::fmt::Display::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ::std::fmt::Display for Radian<T>
|
||||||
|
where T: Real
|
||||||
|
{
|
||||||
|
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result
|
||||||
|
{
|
||||||
|
write!(f, "Radian({})", self.value)
|
||||||
|
}
|
||||||
|
}
|
421
src/trig/trig.rs
Normal file
421
src/trig/trig.rs
Normal file
@ -0,0 +1,421 @@
|
|||||||
|
use ::binding::{CDouble, CFloat};
|
||||||
|
|
||||||
|
use ::real::Real;
|
||||||
|
use ::trig::radian::Radian;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/// The available trigonometric functions.
|
||||||
|
pub trait Trig: Real
|
||||||
|
{
|
||||||
|
/// Computes the cosine of this angle.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use sigils::Radian;
|
||||||
|
/// use std::f64;
|
||||||
|
///
|
||||||
|
/// let x: Radian<f64> = Radian::from(2.0*f64::consts::PI);
|
||||||
|
///
|
||||||
|
/// let abs_difference = (x.cos() - 1.0).abs();
|
||||||
|
///
|
||||||
|
/// assert!(abs_difference < 1e-10);
|
||||||
|
/// ```
|
||||||
|
fn cos<T>(arg: T) -> Self
|
||||||
|
where T: Into<Radian<Self>>;
|
||||||
|
|
||||||
|
/// Computes the sine of this angle.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use sigils::Radian;
|
||||||
|
/// use std::f64;
|
||||||
|
///
|
||||||
|
/// let x: Radian<f64> = Radian::from(f64::consts::PI/2.0);
|
||||||
|
///
|
||||||
|
/// let abs_difference = (x.sin() - 1.0).abs();
|
||||||
|
///
|
||||||
|
/// assert!(abs_difference < 1e-10);
|
||||||
|
/// ```
|
||||||
|
fn sin<T>(arg: T) -> Self
|
||||||
|
where T: Into<Radian<Self>>;
|
||||||
|
|
||||||
|
/// Computes the tangent of this angle.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use sigils::Radian;
|
||||||
|
/// use std::f64;
|
||||||
|
///
|
||||||
|
/// let x: Radian<f64> = Radian::from(f64::consts::PI/4.0);
|
||||||
|
///
|
||||||
|
/// let abs_difference = (x.tan() - 1.0).abs();
|
||||||
|
///
|
||||||
|
/// 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].
|
||||||
|
///
|
||||||
|
///```
|
||||||
|
/// use sigils::{Constants, Radian, Real};
|
||||||
|
///
|
||||||
|
/// let f: Radian<f64>;
|
||||||
|
///
|
||||||
|
/// f = Radian::from(f64::PI / 4.0f64);
|
||||||
|
/// assert!(((f64::PI / 4.0f64) - *Radian::acos(f.cos())) < 1e-10);
|
||||||
|
///```
|
||||||
|
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].
|
||||||
|
///
|
||||||
|
///```
|
||||||
|
/// use sigils::{Constants, Radian, Real};
|
||||||
|
///
|
||||||
|
/// let f: Radian<f64>;
|
||||||
|
///
|
||||||
|
/// f = Radian::from(f64::PI / 4.0f64);
|
||||||
|
/// assert!(((f64::PI / 4.0f64) - *Radian::asin(f.sin())) < 1e-10);
|
||||||
|
///```
|
||||||
|
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];
|
||||||
|
///
|
||||||
|
///```
|
||||||
|
/// use sigils::{Constants, Radian, Real};
|
||||||
|
///
|
||||||
|
/// let f: Radian<f64>;
|
||||||
|
///
|
||||||
|
/// f = Radian::from(f64::PI / 4.0f64);
|
||||||
|
/// assert!(((f64::PI / 4.0f64) - *Radian::atan(f.tan())) < 1e-10);
|
||||||
|
///```
|
||||||
|
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.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use sigils::Radian;
|
||||||
|
/// use sigils::Constants;
|
||||||
|
///
|
||||||
|
/// let e32: f32 = Constants::E;
|
||||||
|
/// let x32: Radian<f32> = Radian::new(1.0f32);
|
||||||
|
/// let f_val32 = x32.cosh();
|
||||||
|
/// let g_val32 = (e32*e32 + 1.0f32)/(2.0f32*e32);
|
||||||
|
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
||||||
|
///
|
||||||
|
/// let e64: f64 = Constants::E;
|
||||||
|
/// let x64: Radian<f64> = Radian::new(1.0f64);
|
||||||
|
/// let f_val64 = x64.cosh();
|
||||||
|
/// let g_val64 = (e64*e64 + 1.0f64)/(2.0f64*e64);
|
||||||
|
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
||||||
|
///
|
||||||
|
/// // Solving cosh() at 1 gives this result
|
||||||
|
/// //assert!(abs_difference32 < 1.0e-10);
|
||||||
|
/// assert!(abs_difference64 < 1.0e-10);
|
||||||
|
/// ```
|
||||||
|
fn cosh(arg: Self) -> Self;
|
||||||
|
|
||||||
|
/// Hyperbolic sine function.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use sigils::Radian;
|
||||||
|
/// use sigils::Constants;
|
||||||
|
///
|
||||||
|
/// let e32: f32 = Constants::E;
|
||||||
|
/// let x32: Radian<f32> = Radian::from(1.0f32);
|
||||||
|
///
|
||||||
|
/// let f_val32 = x32.sinh();
|
||||||
|
/// let g_val32 = (e32*e32 - 1.0f32)/(2.0f32*e32);
|
||||||
|
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
||||||
|
///
|
||||||
|
/// let e64: f64 = Constants::E;
|
||||||
|
/// let x64: Radian<f64> = Radian::from(1.0f64);
|
||||||
|
///
|
||||||
|
/// let f_val64 = x64.sinh();
|
||||||
|
/// let g_val64 = (e64*e64 - 1.0f64)/(2.0f64*e64);
|
||||||
|
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
||||||
|
///
|
||||||
|
/// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
|
||||||
|
/// //assert!(abs_difference32 < 1e-10);
|
||||||
|
/// assert!(abs_difference64 < 1e-10);
|
||||||
|
/// ```
|
||||||
|
fn sinh(arg: Self) -> Self;
|
||||||
|
|
||||||
|
/// Hyperbolic tangent function.
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use sigils::Radian;
|
||||||
|
/// use sigils::Constants;
|
||||||
|
///
|
||||||
|
/// let e32: f32 = Constants::E;
|
||||||
|
/// let x32: Radian<f32> = Radian::from(1.0f32);
|
||||||
|
///
|
||||||
|
/// let f_val32 = x32.tanh();
|
||||||
|
/// let g_val32 = (1.0f32 - e32.powi(-2i32))/(1.0f32 + e32.powi(-2i32));
|
||||||
|
/// let abs_difference32 = (f_val32 - g_val32).abs();
|
||||||
|
///
|
||||||
|
/// let e64: f64 = Constants::E;
|
||||||
|
/// let x64: Radian<f64> = Radian::from(1.0f64);
|
||||||
|
///
|
||||||
|
/// let f_val64 = x64.tanh();
|
||||||
|
/// let g_val64 = (1.0f64 - e64.powi(-2i32))/(1.0f64 + e64.powi(-2i32));
|
||||||
|
/// let abs_difference64 = (f_val64 - g_val64).abs();
|
||||||
|
///
|
||||||
|
/// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
|
||||||
|
/// //assert!(abs_difference32 < 1.0e-10);
|
||||||
|
/// assert!(abs_difference64 < 1.0e-10);
|
||||||
|
/// ```
|
||||||
|
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
|
||||||
|
{
|
||||||
|
::pact::cosf(*arg.into() as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sin<T>(arg: T) -> Self
|
||||||
|
where T: Into<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::sinf(*arg.into() as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tan<T>(arg: T) -> Self
|
||||||
|
where T: Into<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::tanf(*arg.into() as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn acos<T>(arg: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::acosf(arg as CFloat) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asin<T>(arg: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::asinf(arg as CFloat) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atan<T>(arg: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::atanf(arg as CFloat) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atan2<T>(y: Self, x: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::atan2f(y as CFloat, x as CFloat) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn cosh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::coshf(arg as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sinh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::sinhf(arg as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tanh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::tanhf(arg as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn acosh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::acoshf(arg as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asinh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::asinhf(arg as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atanh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::atanhf(arg as CFloat) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trig for f64
|
||||||
|
{
|
||||||
|
fn cos<T>(arg: T) -> Self
|
||||||
|
where T: Into<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::cos(*arg.into() as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sin<T>(arg: T) -> Self
|
||||||
|
where T: Into<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::sin(*arg.into() as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tan<T>(arg: T) -> Self
|
||||||
|
where T: Into<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::tan(*arg.into() as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn acos<T>(arg: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::acos(arg as CDouble) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asin<T>(arg: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::asin(arg as CDouble) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atan<T>(arg: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::atan(arg as CDouble) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atan2<T>(y: Self, x: Self) -> T
|
||||||
|
where T: From<Radian<Self>>
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
Radian::new(::pact::atan2(y as CDouble, x as CDouble) as Self).into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn cosh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::cosh(arg as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sinh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::sinh(arg as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tanh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::tanh(arg as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn acosh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::acosh(arg as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn asinh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::asinh(arg as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn atanh(arg: Self) -> Self
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
::pact::atanh(arg as CDouble) as Self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ use ::one::One;
|
|||||||
use ::number::Number;
|
use ::number::Number;
|
||||||
use ::real::Real;
|
use ::real::Real;
|
||||||
use ::trig::Radian;
|
use ::trig::Radian;
|
||||||
|
use ::trig::Trig;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -277,7 +278,7 @@ pub trait Vector<T>: Debug + Display + Clone + Default + Zero + One
|
|||||||
/// Defines the [EuclideanVector][1] trait.
|
/// Defines the [EuclideanVector][1] trait.
|
||||||
///
|
///
|
||||||
/// [1]: https://en.wikipedia.org/wiki/Euclidean_vector
|
/// [1]: https://en.wikipedia.org/wiki/Euclidean_vector
|
||||||
pub trait EuclideanVector<T> : Vector<T> where T: Real
|
pub trait EuclideanVector<T> : Vector<T> where T: Trig
|
||||||
{
|
{
|
||||||
/// Get the length of the Vector.
|
/// Get the length of the Vector.
|
||||||
///
|
///
|
||||||
@ -623,23 +624,23 @@ macro_rules! define_vector
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement the binary operations for this Vector structure.
|
// Implement the binary operations for this Vector structure.
|
||||||
binary_operator_impl!(Add::add, $structName {$($field),+}, Number);
|
binary_operator_impl!(Add::add, Number, $structName {$($field),+});
|
||||||
binary_operator_impl!(Sub::sub, $structName {$($field),+}, Number);
|
binary_operator_impl!(Sub::sub, Number, $structName {$($field),+});
|
||||||
binary_operator_impl!(Mul::mul, $structName {$($field),+}, Number);
|
binary_operator_impl!(Mul::mul, Number, $structName {$($field),+});
|
||||||
binary_operator_impl!(Div::div, $structName {$($field),+}, Number);
|
binary_operator_impl!(Div::div, Number, $structName {$($field),+});
|
||||||
binary_operator_impl!(Rem::rem, $structName {$($field),+}, Number);
|
binary_operator_impl!(Rem::rem, Number, $structName {$($field),+});
|
||||||
|
|
||||||
// Handle the assignment operators.
|
// Handle the assignment operators.
|
||||||
binary_operator_assign_impl!(AddAssign::add_assign,
|
binary_operator_assign_impl!(AddAssign::add_assign,
|
||||||
$structName {$($field),+}, Number);
|
Number, $structName {$($field),+});
|
||||||
binary_operator_assign_impl!(SubAssign::sub_assign,
|
binary_operator_assign_impl!(SubAssign::sub_assign,
|
||||||
$structName {$($field),+}, Number);
|
Number, $structName {$($field),+});
|
||||||
binary_operator_assign_impl!(MulAssign::mul_assign,
|
binary_operator_assign_impl!(MulAssign::mul_assign,
|
||||||
$structName {$($field),+}, Number);
|
Number, $structName {$($field),+});
|
||||||
binary_operator_assign_impl!(DivAssign::div_assign,
|
binary_operator_assign_impl!(DivAssign::div_assign,
|
||||||
$structName {$($field),+}, Number);
|
Number, $structName {$($field),+});
|
||||||
binary_operator_assign_impl!(RemAssign::rem_assign,
|
binary_operator_assign_impl!(RemAssign::rem_assign,
|
||||||
$structName {$($field),+}, Number);
|
Number, $structName {$($field),+});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -908,29 +909,29 @@ impl<T> Vector4<T> where T: Number
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Implement the angle specific portion of the EuclideanVector.
|
// Implement the angle specific portion of the EuclideanVector.
|
||||||
impl<T> EuclideanVector<T> for Vector2<T> where T: Real
|
impl<T> EuclideanVector<T> for Vector2<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn angle(&self, vector: &Vector2<T>) -> Radian<T>
|
fn angle(&self, vector: &Vector2<T>) -> Radian<T>
|
||||||
{
|
{
|
||||||
// Shortcut.
|
// Shortcut.
|
||||||
Radian::atan2(self.perpendicular_dot(vector), self.dot(vector))
|
Trig::atan2(self.perpendicular_dot(vector), self.dot(vector))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EuclideanVector<T> for Vector3<T> where T: Real
|
impl<T> EuclideanVector<T> for Vector3<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn angle(&self, vector: &Vector3<T>) -> Radian<T>
|
fn angle(&self, vector: &Vector3<T>) -> Radian<T>
|
||||||
{
|
{
|
||||||
// Shortcut.
|
// Shortcut.
|
||||||
Radian::atan2(self.cross(vector).get_length(), self.dot(vector))
|
Trig::atan2(self.cross(vector).get_length(), self.dot(vector))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EuclideanVector<T> for Vector4<T> where T: Real
|
impl<T> EuclideanVector<T> for Vector4<T> where T: Trig
|
||||||
{
|
{
|
||||||
fn angle(&self, vector: &Vector4<T>) -> Radian<T>
|
fn angle(&self, vector: &Vector4<T>) -> Radian<T>
|
||||||
{
|
{
|
||||||
// The basic equation, this would work for any size Vector.
|
// The basic equation, this would work for any size Vector.
|
||||||
Radian::acos(self.dot(vector) / (self.get_length()*vector.get_length()))
|
Trig::acos(self.dot(vector) / (self.get_length()*vector.get_length()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user