diff --git a/src/funs/transform.rs b/src/funs/transform.rs index 7727fde..1fc58b1 100644 --- a/src/funs/transform.rs +++ b/src/funs/transform.rs @@ -1,17 +1,21 @@ use num::Num; use ncast::*; -use funs::exp::*; +use ntrait::Float; +use funs::exp::Exp; use funs::trig::*; use matrix::Mat4; -pub fn mat4_from_rotation(angle: T, axis: Vec3) -> Mat4 { - let angle_rad = radians(&angle); - let c = cos(&angle_rad); - let s = sin(&angle_rad); - +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); let _0: T = cast(0); let _1: T = cast(1); - let t = _1 - c; + let t: T = _1 - c; Mat4::new(t * axis.x * axis.x + c, t * axis.x * axis.y + s * axis.z, t * axis.x * axis.z - s * axis.y, _0, t * axis.x * axis.y - s * axis.z, t * axis.y * axis.y + c, t * axis.y * axis.z + s * axis.x, _0, diff --git a/src/funs/trig.rs b/src/funs/trig.rs index 8f4afb6..82e2f7f 100644 --- a/src/funs/trig.rs +++ b/src/funs/trig.rs @@ -1,274 +1,270 @@ use ncast::*; -use vector::*; +use ntrait::Float; +use vector::{Vec3, Vec2, Vec4}; + +pub enum Radians = ThetaT; + +pub impl Radians { + #[inline(always)] + pure fn to_degrees() -> Degrees { + Degrees(*self * cast(180f64 / f64::consts::pi)) + } +} + +pub enum Degrees = ThetaT; + +pub impl Degrees { + #[inline(always)] + pure fn to_radians() -> Radians { + Radians(*self * cast(f64::consts::pi / 180f64)) + } +} /** * Angle and Trigonometry Functions */ -pub trait Trig { - pure fn radians() -> self; - pure fn degrees() -> self; - 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; +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; } -#[inline(always)] pub pure fn radians(degrees: &T) -> T { degrees.radians() } -#[inline(always)] pub pure fn degrees(radians: &T) -> T { radians.degrees() } -#[inline(always)] pub pure fn sin(angle: &T) -> T { angle.sin() } -#[inline(always)] pub pure fn cos(angle: &T) -> T { angle.cos() } -#[inline(always)] pub pure fn tan(angle: &T) -> T { angle.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 f32: Trig { - #[inline(always)] pure fn radians() -> f32 { self * (f32::consts::pi / 180f32) } - #[inline(always)] pure fn degrees() -> f32 { self * (180f32 / f32::consts::pi) } - #[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 +< + 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 impl f64: Trig { - #[inline(always)] pure fn radians() -> f64 { self * (f64::consts::pi / 180f64) } - #[inline(always)] pure fn degrees() -> f64 { self * (180f64 / f64::consts::pi) } - #[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) } -} +#[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() } -pub impl float: Trig { - #[inline(always)] pure fn radians() -> float { self * (float::consts::pi / 180f) } - #[inline(always)] pure fn degrees() -> float { self * (180f / float::consts::pi) } - #[inline(always)] pure fn sin() -> float { cast(float::sin(cast(self))) } - #[inline(always)] pure fn cos() -> float { cast(float::cos(cast(self))) } - #[inline(always)] pure fn tan() -> float { cast(float::tan(cast(self))) } - #[inline(always)] pure fn asin() -> float { cast(float::asin(cast(self))) } - #[inline(always)] pure fn acos() -> float { cast(float::acos(cast(self))) } - #[inline(always)] pure fn atan() -> float { cast(float::atan(cast(self))) } - #[inline(always)] pure fn sinh() -> float { cast(float::sinh(cast(self))) } - #[inline(always)] pure fn cosh() -> float { cast(float::cosh(cast(self))) } - #[inline(always)] pure fn tanh() -> float { cast(float::tanh(cast(self))) } -} - -pub impl Vec2: Trig { - #[inline(always)] pure fn radians() -> Vec2 { - Vec2::new(radians(&self[0]), - radians(&self[1])) - } - - #[inline(always)] pure fn degrees() -> Vec2 { - Vec2::new(degrees(&self[0]), - degrees(&self[1])) - } - - #[inline(always)] pure fn sin() -> Vec2 { +pub impl +< + ThetaT:Copy Trig, + T:NumCast +> +Vec2: Trig> { + #[inline(always)] + pure fn sin() -> Vec2 { Vec2::new(sin(&self[0]), sin(&self[1])) } - #[inline(always)] pure fn cos() -> Vec2 { + #[inline(always)] + pure fn cos() -> Vec2 { Vec2::new(cos(&self[0]), cos(&self[1])) } - #[inline(always)] pure fn tan() -> Vec2 { + #[inline(always)] + pure fn tan() -> Vec2 { Vec2::new(tan(&self[0]), tan(&self[1])) } - #[inline(always)] pure fn asin() -> Vec2 { + #[inline(always)] + pure fn asin() -> Vec2 { Vec2::new(asin(&self[0]), asin(&self[1])) } - #[inline(always)] pure fn acos() -> Vec2 { + #[inline(always)] + pure fn acos() -> Vec2 { Vec2::new(acos(&self[0]), acos(&self[1])) } - #[inline(always)] pure fn atan() -> Vec2 { + #[inline(always)] + pure fn atan() -> Vec2 { Vec2::new(atan(&self[0]), atan(&self[1])) } - #[inline(always)] pure fn sinh() -> Vec2 { + #[inline(always)] + pure fn sinh() -> Vec2 { Vec2::new(sinh(&self[0]), sinh(&self[1])) } - #[inline(always)] pure fn cosh() -> Vec2 { + #[inline(always)] + pure fn cosh() -> Vec2 { Vec2::new(cosh(&self[0]), cosh(&self[1])) } - #[inline(always)] pure fn tanh() -> Vec2 { + #[inline(always)] + pure fn tanh() -> Vec2 { Vec2::new(tanh(&self[0]), tanh(&self[1])) } } -pub impl Vec3: Trig { - #[inline(always)] pure fn radians() -> Vec3 { - Vec3::new(radians(&self[0]), - radians(&self[1]), - radians(&self[2])) - } - - #[inline(always)] pure fn degrees() -> Vec3 { - Vec3::new(degrees(&self[0]), - degrees(&self[1]), - degrees(&self[2])) - } - - #[inline(always)] pure fn sin() -> Vec3 { +pub impl +< + ThetaT:Copy Trig, + T:NumCast +> +Vec3: Trig> { + #[inline(always)] + pure fn sin() -> Vec3 { Vec3::new(sin(&self[0]), sin(&self[1]), sin(&self[2])) } - #[inline(always)] pure fn cos() -> Vec3 { + #[inline(always)] + pure fn cos() -> Vec3 { Vec3::new(cos(&self[0]), cos(&self[1]), cos(&self[2])) } - #[inline(always)] pure fn tan() -> Vec3 { + #[inline(always)] + pure fn tan() -> Vec3 { Vec3::new(tan(&self[0]), tan(&self[1]), tan(&self[2])) } - #[inline(always)] pure fn asin() -> Vec3 { + #[inline(always)] + pure fn asin() -> Vec3 { Vec3::new(asin(&self[0]), asin(&self[1]), asin(&self[2])) } - #[inline(always)] pure fn acos() -> Vec3 { + #[inline(always)] + pure fn acos() -> Vec3 { Vec3::new(acos(&self[0]), acos(&self[1]), acos(&self[2])) } - #[inline(always)] pure fn atan() -> Vec3 { + #[inline(always)] + pure fn atan() -> Vec3 { Vec3::new(atan(&self[0]), atan(&self[1]), atan(&self[2])) } - #[inline(always)] pure fn sinh() -> Vec3 { + #[inline(always)] + pure fn sinh() -> Vec3 { Vec3::new(sinh(&self[0]), sinh(&self[1]), sinh(&self[2])) } - #[inline(always)] pure fn cosh() -> Vec3 { + #[inline(always)] + pure fn cosh() -> Vec3 { Vec3::new(cosh(&self[0]), cosh(&self[1]), cosh(&self[2])) } - #[inline(always)] pure fn tanh() -> Vec3 { + #[inline(always)] + pure fn tanh() -> Vec3 { Vec3::new(tanh(&self[0]), tanh(&self[1]), tanh(&self[2])) } } -pub impl Vec4: Trig { - #[inline(always)] pure fn radians() -> Vec4 { - Vec4::new(radians(&self[0]), - radians(&self[1]), - radians(&self[2]), - radians(&self[3])) - } - - #[inline(always)] pure fn degrees() -> Vec4 { - Vec4::new(degrees(&self[0]), - degrees(&self[1]), - degrees(&self[2]), - degrees(&self[3])) - } - - #[inline(always)] pure fn sin() -> Vec4 { +pub impl +< + ThetaT:Copy Trig, + T:NumCast +> +Vec4: Trig> { + #[inline(always)] + pure fn sin() -> Vec4 { Vec4::new(sin(&self[0]), sin(&self[1]), sin(&self[2]), sin(&self[3])) } - #[inline(always)] pure fn cos() -> Vec4 { + #[inline(always)] + pure fn cos() -> Vec4 { Vec4::new(cos(&self[0]), cos(&self[1]), cos(&self[2]), cos(&self[3])) } - #[inline(always)] pure fn tan() -> Vec4 { + #[inline(always)] + pure fn tan() -> Vec4 { Vec4::new(tan(&self[0]), tan(&self[1]), tan(&self[2]), tan(&self[3])) } - #[inline(always)] pure fn asin() -> Vec4 { + #[inline(always)] + pure fn asin() -> Vec4 { Vec4::new(asin(&self[0]), asin(&self[1]), asin(&self[2]), asin(&self[3])) } - #[inline(always)] pure fn acos() -> Vec4 { + #[inline(always)] + pure fn acos() -> Vec4 { Vec4::new(acos(&self[0]), acos(&self[1]), acos(&self[2]), acos(&self[3])) } - #[inline(always)] pure fn atan() -> Vec4 { + #[inline(always)] + pure fn atan() -> Vec4 { Vec4::new(atan(&self[0]), atan(&self[1]), atan(&self[2]), atan(&self[3])) } - #[inline(always)] pure fn sinh() -> Vec4 { + #[inline(always)] + pure fn sinh() -> Vec4 { Vec4::new(sinh(&self[0]), sinh(&self[1]), sinh(&self[2]), sinh(&self[3])) } - #[inline(always)] pure fn cosh() -> Vec4 { + #[inline(always)] + pure fn cosh() -> Vec4 { Vec4::new(cosh(&self[0]), cosh(&self[1]), cosh(&self[2]), cosh(&self[3])) } - #[inline(always)] pure fn tanh() -> Vec4 { + #[inline(always)] + pure fn tanh() -> Vec4 { Vec4::new(tanh(&self[0]), tanh(&self[1]), tanh(&self[2]),