From f0ca91e4524b6c6cb6beeedda95461a8a17232c5 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Fri, 9 Nov 2012 16:18:14 +1000 Subject: [PATCH] Update Trig, add AngleConv trait, remove Degrees and Radians types for the time being --- src/funs/test/test_transform.rs | 31 ++++-- src/funs/transform.rs | 12 +-- src/funs/trig.rs | 184 +++++++++++++++++++++----------- 3 files changed, 146 insertions(+), 81 deletions(-) diff --git a/src/funs/test/test_transform.rs b/src/funs/test/test_transform.rs index 76ca633..63fdb89 100644 --- a/src/funs/test/test_transform.rs +++ b/src/funs/test/test_transform.rs @@ -4,12 +4,27 @@ use vector::{Vec3, Vec4}; #[test] fn test_mat4_from_rotation() { - let a_theta = Degrees(180f).to_radians(); - let a_axis = Vec3::unit_z(); - let a_pos = Vec4::new(1f32, 0f32, 0f32, 1f32); - - let a_tform = mat4_from_rotation(a_theta, a_axis).mul_v(&a_pos); - let a_expected = Vec4::new(-1f32, 0f32, 0f32, 1f32); - - assert a_tform == a_expected; + { + let pos = Vec4::new(1f32, 0f32, 0f32, 1f32); + let tform = mat4_from_rotation(180f32, Vec3::unit_z()); + let newpos = tform.mul_v(&pos); + + let expected = Vec4::new(-1f32, 0f32, 0f32, 1f32); + + assert newpos == expected; + } + { + let pos = Vec4::new(4f32, 0f32, 0f32, 1f32); + + let tform_a = mat4_from_rotation(90f32, Vec3::unit_y()); + let tform_b = mat4_from_rotation(90f32, -Vec3::unit_y()); + let newpos_a = tform_a.mul_v(&pos); + let newpos_b = tform_b.mul_v(&pos); + + let expected_a = Vec4::new(0f32, 0f32, -4f32, 1f32); + let expected_b = Vec4::new(0f32, 0f32, 4f32, 1f32); + + assert newpos_a == expected_a; + assert newpos_b == expected_b; + } } \ No newline at end of file diff --git a/src/funs/transform.rs b/src/funs/transform.rs index 1fc58b1..7e8a99a 100644 --- a/src/funs/transform.rs +++ b/src/funs/transform.rs @@ -5,14 +5,10 @@ use funs::exp::Exp; use funs::trig::*; use matrix::Mat4; -pub fn mat4_from_rotation -< - ThetaT:NumCast Float, - T:Copy Num NumCast -> -(theta: Radians, axis: Vec3) -> Mat4 { - let c: T = cos(&theta); - let s: T = sin(&theta); +pub fn mat4_from_rotation(theta: T, axis: Vec3) -> Mat4 { + let rad = radians(&theta); + let c: T = cos(&rad); + let s: T = sin(&rad); let _0: T = cast(0); let _1: T = cast(1); let t: T = _1 - c; diff --git a/src/funs/trig.rs b/src/funs/trig.rs index 82e2f7f..7a0c9e9 100644 --- a/src/funs/trig.rs +++ b/src/funs/trig.rs @@ -1,73 +1,137 @@ use ncast::*; -use ntrait::Float; use vector::{Vec3, Vec2, Vec4}; -pub enum Radians = ThetaT; +pub trait AngleConv { + pure fn to_degrees() -> self; + pure fn to_radians() -> self; +} -pub impl Radians { +#[inline(always)] pub pure fn degrees(theta: &T) -> T { theta.to_degrees() } +#[inline(always)] pub pure fn radians(theta: &T) -> T { theta.to_radians() } + +pub impl f32: AngleConv { + #[inline(always)] pure fn to_degrees() -> f32 { self * (180f32 / f32::consts::pi) } + #[inline(always)] pure fn to_radians() -> f32 { self * (f32::consts::pi / 180f32) } +} + +pub impl f64: AngleConv { + #[inline(always)] pure fn to_degrees() -> f64 { self * (180f64 / f64::consts::pi) } + #[inline(always)] pure fn to_radians() -> f64 { self * (f64::consts::pi / 180f64) } +} + +pub impl float: AngleConv { + #[inline(always)] pure fn to_degrees() -> float { self * (180f / float::consts::pi) } + #[inline(always)] pure fn to_radians() -> float { self * (float::consts::pi / 180f) } +} + +pub impl Vec2: AngleConv { #[inline(always)] - pure fn to_degrees() -> Degrees { - Degrees(*self * cast(180f64 / f64::consts::pi)) + pure fn to_degrees() -> Vec2 { + Vec2::new(degrees(&self[0]), + degrees(&self[1])) + } + + #[inline(always)] + pure fn to_radians() -> Vec2 { + Vec2::new(radians(&self[0]), + radians(&self[1])) } } -pub enum Degrees = ThetaT; - -pub impl Degrees { +pub impl Vec3: AngleConv { #[inline(always)] - pure fn to_radians() -> Radians { - Radians(*self * cast(f64::consts::pi / 180f64)) + pure fn to_degrees() -> Vec3 { + Vec3::new(degrees(&self[0]), + degrees(&self[1]), + degrees(&self[2])) + } + + #[inline(always)] + pure fn to_radians() -> Vec3 { + Vec3::new(radians(&self[0]), + radians(&self[1]), + radians(&self[2])) } } -/** - * Angle and Trigonometry Functions - */ -pub trait Trig { - pure fn sin() -> Result; - pure fn cos() -> Result; - pure fn tan() -> Result; - pure fn asin() -> Result; - pure fn acos() -> Result; - pure fn atan() -> Result; - pure fn sinh() -> Result; - pure fn cosh() -> Result; - pure fn tanh() -> Result; +pub impl Vec4: AngleConv { + #[inline(always)] + pure fn to_degrees() -> Vec4 { + Vec4::new(degrees(&self[0]), + degrees(&self[1]), + degrees(&self[2]), + degrees(&self[3])) + } + + #[inline(always)] + pure fn to_radians() -> Vec4 { + Vec4::new(radians(&self[0]), + radians(&self[1]), + radians(&self[2]), + radians(&self[3])) + } } -pub impl -< - ThetaT:Copy NumCast Float, - Result:NumCast -> -Radians: Trig { - #[inline(always)] pure fn sin() -> Result { cast(f64::sin (cast(*self))) } - #[inline(always)] pure fn cos() -> Result { cast(f64::cos (cast(*self))) } - #[inline(always)] pure fn tan() -> Result { cast(f64::tan (cast(*self))) } - #[inline(always)] pure fn asin() -> Result { cast(f64::asin(cast(*self))) } - #[inline(always)] pure fn acos() -> Result { cast(f64::acos(cast(*self))) } - #[inline(always)] pure fn atan() -> Result { cast(f64::atan(cast(*self))) } - #[inline(always)] pure fn sinh() -> Result { cast(f64::sinh(cast(*self))) } - #[inline(always)] pure fn cosh() -> Result { cast(f64::cosh(cast(*self))) } - #[inline(always)] pure fn tanh() -> Result { cast(f64::tanh(cast(*self))) } + +pub trait Trig { + pure fn sin() -> self; + pure fn cos() -> self; + pure fn tan() -> self; + pure fn asin() -> self; + pure fn acos() -> self; + pure fn atan() -> self; + pure fn sinh() -> self; + pure fn cosh() -> self; + pure fn tanh() -> self; } -#[inline(always)] pub pure fn sin, Result:NumCast>(angle: &T) -> Result { angle.sin() } -#[inline(always)] pub pure fn cos, Result:NumCast>(angle: &T) -> Result { angle.cos() } -#[inline(always)] pub pure fn tan, Result:NumCast>(angle: &T) -> Result { angle.tan() } -#[inline(always)] pub pure fn asin, Result:NumCast>(x: &T) -> Result { x.asin() } -#[inline(always)] pub pure fn acos, Result:NumCast>(x: &T) -> Result { x.acos() } -#[inline(always)] pub pure fn atan, Result:NumCast>(x: &T) -> Result { x.atan() } -#[inline(always)] pub pure fn sinh, Result:NumCast>(x: &T) -> Result { x.sinh() } -#[inline(always)] pub pure fn cosh, Result:NumCast>(x: &T) -> Result { x.cosh() } -#[inline(always)] pub pure fn tanh, Result:NumCast>(x: &T) -> Result { x.tanh() } +#[inline(always)] pub pure fn sin(theta: &T) -> T { theta.sin() } +#[inline(always)] pub pure fn cos(theta: &T) -> T { theta.cos() } +#[inline(always)] pub pure fn tan(theta: &T) -> T { theta.tan() } +#[inline(always)] pub pure fn asin(x: &T) -> T { x.asin() } +#[inline(always)] pub pure fn acos(x: &T) -> T { x.acos() } +#[inline(always)] pub pure fn atan(x: &T) -> T { x.atan() } +#[inline(always)] pub pure fn sinh(x: &T) -> T { x.sinh() } +#[inline(always)] pub pure fn cosh(x: &T) -> T { x.cosh() } +#[inline(always)] pub pure fn tanh(x: &T) -> T { x.tanh() } -pub impl -< - ThetaT:Copy Trig, - T:NumCast -> -Vec2: Trig> { +pub impl f32: Trig { + #[inline(always)] pure fn sin() -> f32 { f32::sin (self) } + #[inline(always)] pure fn cos() -> f32 { f32::cos (self) } + #[inline(always)] pure fn tan() -> f32 { f32::tan (self) } + #[inline(always)] pure fn asin() -> f32 { f32::asin(self) } + #[inline(always)] pure fn acos() -> f32 { f32::acos(self) } + #[inline(always)] pure fn atan() -> f32 { f32::atan(self) } + #[inline(always)] pure fn sinh() -> f32 { f32::sinh(self) } + #[inline(always)] pure fn cosh() -> f32 { f32::cosh(self) } + #[inline(always)] pure fn tanh() -> f32 { f32::tanh(self) } +} + +pub impl f64: Trig { + #[inline(always)] pure fn sin() -> f64 { f64::sin (self) } + #[inline(always)] pure fn cos() -> f64 { f64::cos (self) } + #[inline(always)] pure fn tan() -> f64 { f64::tan (self) } + #[inline(always)] pure fn asin() -> f64 { f64::asin(self) } + #[inline(always)] pure fn acos() -> f64 { f64::acos(self) } + #[inline(always)] pure fn atan() -> f64 { f64::atan(self) } + #[inline(always)] pure fn sinh() -> f64 { f64::sinh(self) } + #[inline(always)] pure fn cosh() -> f64 { f64::cosh(self) } + #[inline(always)] pure fn tanh() -> f64 { f64::tanh(self) } +} + +pub impl float: Trig { + #[inline(always)] pure fn sin() -> float { cast(f64::sin (cast(self))) } + #[inline(always)] pure fn cos() -> float { cast(f64::cos (cast(self))) } + #[inline(always)] pure fn tan() -> float { cast(f64::tan (cast(self))) } + #[inline(always)] pure fn asin() -> float { cast(f64::asin(cast(self))) } + #[inline(always)] pure fn acos() -> float { cast(f64::acos(cast(self))) } + #[inline(always)] pure fn atan() -> float { cast(f64::atan(cast(self))) } + #[inline(always)] pure fn sinh() -> float { cast(f64::sinh(cast(self))) } + #[inline(always)] pure fn cosh() -> float { cast(f64::cosh(cast(self))) } + #[inline(always)] pure fn tanh() -> float { cast(f64::tanh(cast(self))) } +} + +pub impl Vec2: Trig { #[inline(always)] pure fn sin() -> Vec2 { Vec2::new(sin(&self[0]), @@ -123,12 +187,7 @@ Vec2: Trig> { } } -pub impl -< - ThetaT:Copy Trig, - T:NumCast -> -Vec3: Trig> { +pub impl Vec3: Trig { #[inline(always)] pure fn sin() -> Vec3 { Vec3::new(sin(&self[0]), @@ -193,12 +252,7 @@ Vec3: Trig> { } } -pub impl -< - ThetaT:Copy Trig, - T:NumCast -> -Vec4: Trig> { +pub impl Vec4: Trig { #[inline(always)] pure fn sin() -> Vec4 { Vec4::new(sin(&self[0]),