Add float constants to `BaseFloat`.

Fix #42.
This commit is contained in:
Sébastien Crozet 2014-11-25 11:11:50 +01:00
parent 40c14ace39
commit 3317e057f5
3 changed files with 136 additions and 15 deletions

View File

@ -585,11 +585,10 @@ pub fn prepend_rotation<V, M: Rotation<V>>(m: &M, v: &V) -> M {
/// ///
/// ```rust /// ```rust
/// extern crate "nalgebra" as na; /// extern crate "nalgebra" as na;
/// use std::num::Float; /// use na::{BaseFloat, Rot3, Vec3};
/// use na::{Rot3, Vec3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * Float::pi())); /// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * BaseFloat::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0); /// let v = Vec3::new(1.0, 0.0, 0.0);
/// ///
/// let tv = na::rotate(&t, &v); /// let tv = na::rotate(&t, &v);
@ -607,11 +606,10 @@ pub fn rotate<V, M: Rotate<V>>(m: &M, v: &V) -> V {
/// ///
/// ```rust /// ```rust
/// extern crate "nalgebra" as na; /// extern crate "nalgebra" as na;
/// use std::num::Float; /// use na::{BaseFloat, Rot3, Vec3};
/// use na::{Rot3, Vec3};
/// ///
/// fn main() { /// fn main() {
/// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * Float::pi())); /// let t = Rot3::new(Vec3::new(0.0f64, 0.0, 0.5 * BaseFloat::pi()));
/// let v = Vec3::new(1.0, 0.0, 0.0); /// let v = Vec3::new(1.0, 0.0, 0.0);
/// ///
/// let tv = na::inv_rotate(&t, &v); /// let tv = na::inv_rotate(&t, &v);

View File

@ -1,5 +1,7 @@
//! Traits giving structural informations on linear algebra objects or the space they live in. //! Traits giving structural informations on linear algebra objects or the space they live in.
use std::f32;
use std::f64;
use std::num::{Int, Float, FloatMath}; use std::num::{Int, Float, FloatMath};
use std::slice::{Items, MutItems}; use std::slice::{Items, MutItems};
use traits::operations::{RMul, LMul, Axpy, Transpose, Inv, Absolute}; use traits::operations::{RMul, LMul, Axpy, Transpose, Inv, Absolute};
@ -12,12 +14,38 @@ pub trait BaseNum: Zero + One + Add<Self, Self> + Sub<Self, Self> + Mul<Self, Se
/// Basic floating-point number numeric trait. /// Basic floating-point number numeric trait.
pub trait BaseFloat: FloatMath + BaseNum { pub trait BaseFloat: FloatMath + BaseNum {
} /// Archimedes' constant.
fn pi() -> Self;
/// 2.0 * pi.
fn two_pi() -> Self;
/// pi / 2.0.
fn frac_pi_2() -> Self;
/// pi / 3.0.
fn frac_pi_3() -> Self;
/// pi / 4.0.
fn frac_pi_4() -> Self;
/// pi / 6.0.
fn frac_pi_6() -> Self;
/// pi / 8.0.
fn frac_pi_8() -> Self;
/// 1.0 / pi.
fn frac_1_pi() -> Self;
/// 2.0 / pi.
fn frac_2_pi() -> Self;
/// 2.0 / sqrt(pi).
fn frac_2_sqrtpi() -> Self;
impl BaseNum for f32 { } /// Euler's number.
impl BaseNum for f64 { } fn e() -> Self;
impl BaseFloat for f32 { } /// log2(e).
impl BaseFloat for f64 { } fn log2_e() -> Self;
/// log10(e).
fn log10_e() -> Self;
/// ln(2.0).
fn ln_2() -> Self;
/// ln(10.0).
fn ln_10() -> Self;
}
/// Traits of objects which can be created from an object of type `T`. /// Traits of objects which can be created from an object of type `T`.
pub trait Cast<T> { pub trait Cast<T> {
@ -260,6 +288,10 @@ pub trait FloatPnt<N: BaseFloat, V: Norm<N>>: NumPnt<N, V> {
* *
* *
*/ */
// Zero and One
macro_rules! impl_zero_one( macro_rules! impl_zero_one(
($n: ty, $zero: expr, $one: expr) => { ($n: ty, $zero: expr, $one: expr) => {
impl Zero for $n { impl Zero for $n {
@ -295,6 +327,8 @@ impl_zero_one!(u32, 0, 1)
impl_zero_one!(u64, 0, 1) impl_zero_one!(u64, 0, 1)
impl_zero_one!(uint, 0, 1) impl_zero_one!(uint, 0, 1)
// Bounded
macro_rules! impl_bounded( macro_rules! impl_bounded(
($n: ty, $min: expr, $max: expr) => { ($n: ty, $min: expr, $max: expr) => {
impl Bounded for $n { impl Bounded for $n {
@ -323,3 +357,93 @@ impl_bounded!(u16, Int::min_value(), Int::max_value())
impl_bounded!(u32, Int::min_value(), Int::max_value()) impl_bounded!(u32, Int::min_value(), Int::max_value())
impl_bounded!(u64, Int::min_value(), Int::max_value()) impl_bounded!(u64, Int::min_value(), Int::max_value())
impl_bounded!(uint, Int::min_value(), Int::max_value()) impl_bounded!(uint, Int::min_value(), Int::max_value())
// BaseFloat
macro_rules! impl_base_float(
($n: ident) => {
impl BaseFloat for $n {
/// Archimedes' constant.
fn pi() -> $n {
$n::consts::PI
}
/// 2.0 * pi.
fn two_pi() -> $n {
$n::consts::PI_2
}
/// pi / 2.0.
fn frac_pi_2() -> $n {
$n::consts::FRAC_PI_2
}
/// pi / 3.0.
fn frac_pi_3() -> $n {
$n::consts::FRAC_PI_3
}
/// pi / 4.0.
fn frac_pi_4() -> $n {
$n::consts::FRAC_PI_4
}
/// pi / 6.0.
fn frac_pi_6() -> $n {
$n::consts::FRAC_PI_6
}
/// pi / 8.0.
fn frac_pi_8() -> $n {
$n::consts::FRAC_PI_8
}
/// 1.0 / pi.
fn frac_1_pi() -> $n {
$n::consts::FRAC_1_PI
}
/// 2.0 / pi.
fn frac_2_pi() -> $n {
$n::consts::FRAC_2_PI
}
/// 2.0 / sqrt(pi).
fn frac_2_sqrtpi() -> $n {
$n::consts::FRAC_2_SQRTPI
}
/// Euler's number.
fn e() -> $n {
$n::consts::E
}
/// log2(e).
fn log2_e() -> $n {
$n::consts::LOG2_E
}
/// log10(e).
fn log10_e() -> $n {
$n::consts::LOG10_E
}
/// ln(2.0).
fn ln_2() -> $n {
$n::consts::LN_2
}
/// ln(10.0).
fn ln_10() -> $n {
$n::consts::LN_10
}
}
}
)
impl BaseNum for f32 { }
impl BaseNum for f64 { }
impl_base_float!(f32)
impl_base_float!(f64)

View File

@ -2,11 +2,10 @@
extern crate "nalgebra" as na; extern crate "nalgebra" as na;
use std::num::Float;
use std::rand::random; use std::rand::random;
use std::cmp::{min, max}; use std::cmp::{min, max};
use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3, use na::{Vec1, Vec3, Mat1, Mat2, Mat3, Mat4, Mat5, Mat6, Rot3, Persp3, PerspMat3, Ortho3, OrthoMat3,
DMat, DVec, Row, Col}; DMat, DVec, Row, Col, BaseFloat};
macro_rules! test_inv_mat_impl( macro_rules! test_inv_mat_impl(
($t: ty) => ( ($t: ty) => (
@ -131,7 +130,7 @@ fn test_inv_mat6() {
fn test_rotation2() { fn test_rotation2() {
for _ in range(0u, 10000) { for _ in range(0u, 10000) {
let randmat: na::Rot2<f64> = na::one(); let randmat: na::Rot2<f64> = na::one();
let ang = Vec1::new(na::abs(&random::<f64>()) % Float::pi()); let ang = Vec1::new(na::abs(&random::<f64>()) % BaseFloat::pi());
assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang)); assert!(na::approx_eq(&na::rotation(&na::append_rotation(&randmat, &ang)), &ang));
} }
@ -149,7 +148,7 @@ fn test_inv_rotation3() {
for _ in range(0u, 10000) { for _ in range(0u, 10000) {
let randmat: Rot3<f64> = na::one(); let randmat: Rot3<f64> = na::one();
let dir: Vec3<f64> = random(); let dir: Vec3<f64> = random();
let ang = na::normalize(&dir) * (na::abs(&random::<f64>()) % Float::pi()); let ang = na::normalize(&dir) * (na::abs(&random::<f64>()) % BaseFloat::pi());
let rot = na::append_rotation(&randmat, &ang); let rot = na::append_rotation(&randmat, &ang);
assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one())); assert!(na::approx_eq(&(na::transpose(&rot) * rot), &na::one()));