Add Radian and Degree types

This commit is contained in:
Brendan Zabarauskas 2012-11-08 11:48:29 +10:00
parent c30aca03e6
commit e06117f29c
2 changed files with 137 additions and 137 deletions

View file

@ -1,17 +1,21 @@
use num::Num; use num::Num;
use ncast::*; use ncast::*;
use funs::exp::*; use ntrait::Float;
use funs::exp::Exp;
use funs::trig::*; use funs::trig::*;
use matrix::Mat4; use matrix::Mat4;
pub fn mat4_from_rotation<T:Copy Num NumCast Exp Trig>(angle: T, axis: Vec3<T>) -> Mat4<T> { pub fn mat4_from_rotation
let angle_rad = radians(&angle); <
let c = cos(&angle_rad); ThetaT:NumCast Float,
let s = sin(&angle_rad); T:Copy Num NumCast
>
(theta: Radians<ThetaT>, axis: Vec3<T>) -> Mat4<T> {
let c: T = cos(&theta);
let s: T = sin(&theta);
let _0: T = cast(0); let _0: T = cast(0);
let _1: T = cast(1); 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, 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, t * axis.x * axis.y - s * axis.z, t * axis.y * axis.y + c, t * axis.y * axis.z + s * axis.x, _0,

View file

@ -1,274 +1,270 @@
use ncast::*; use ncast::*;
use vector::*; use ntrait::Float;
use vector::{Vec3, Vec2, Vec4};
pub enum Radians<ThetaT: Float> = ThetaT;
pub impl<ThetaT:Num NumCast Float> Radians<ThetaT> {
#[inline(always)]
pure fn to_degrees() -> Degrees<ThetaT> {
Degrees(*self * cast(180f64 / f64::consts::pi))
}
}
pub enum Degrees<ThetaT: Float> = ThetaT;
pub impl<ThetaT:Num NumCast Float> Degrees<ThetaT> {
#[inline(always)]
pure fn to_radians() -> Radians<ThetaT> {
Radians(*self * cast(f64::consts::pi / 180f64))
}
}
/** /**
* Angle and Trigonometry Functions * Angle and Trigonometry Functions
*/ */
pub trait Trig { pub trait Trig<Result> {
pure fn radians() -> self; pure fn sin() -> Result;
pure fn degrees() -> self; pure fn cos() -> Result;
pure fn sin() -> self; pure fn tan() -> Result;
pure fn cos() -> self; pure fn asin() -> Result;
pure fn tan() -> self; pure fn acos() -> Result;
pure fn asin() -> self; pure fn atan() -> Result;
pure fn acos() -> self; pure fn sinh() -> Result;
pure fn atan() -> self; pure fn cosh() -> Result;
pure fn sinh() -> self; pure fn tanh() -> Result;
pure fn cosh() -> self;
pure fn tanh() -> self;
} }
#[inline(always)] pub pure fn radians<T:Trig>(degrees: &T) -> T { degrees.radians() } pub impl
#[inline(always)] pub pure fn degrees<T:Trig>(radians: &T) -> T { radians.degrees() } <
#[inline(always)] pub pure fn sin<T:Trig>(angle: &T) -> T { angle.sin() } ThetaT:Copy NumCast Float,
#[inline(always)] pub pure fn cos<T:Trig>(angle: &T) -> T { angle.cos() } Result:NumCast
#[inline(always)] pub pure fn tan<T:Trig>(angle: &T) -> T { angle.tan() } >
#[inline(always)] pub pure fn asin<T:Trig>(x: &T) -> T { x.asin() } Radians<ThetaT>: Trig<Result> {
#[inline(always)] pub pure fn acos<T:Trig>(x: &T) -> T { x.acos() } #[inline(always)] pure fn sin() -> Result { cast(f64::sin (cast(*self))) }
#[inline(always)] pub pure fn atan<T:Trig>(x: &T) -> T { x.atan() } #[inline(always)] pure fn cos() -> Result { cast(f64::cos (cast(*self))) }
#[inline(always)] pub pure fn sinh<T:Trig>(x: &T) -> T { x.sinh() } #[inline(always)] pure fn tan() -> Result { cast(f64::tan (cast(*self))) }
#[inline(always)] pub pure fn cosh<T:Trig>(x: &T) -> T { x.cosh() } #[inline(always)] pure fn asin() -> Result { cast(f64::asin(cast(*self))) }
#[inline(always)] pub pure fn tanh<T:Trig>(x: &T) -> T { x.tanh() } #[inline(always)] pure fn acos() -> Result { cast(f64::acos(cast(*self))) }
#[inline(always)] pure fn atan() -> Result { cast(f64::atan(cast(*self))) }
pub impl f32: Trig { #[inline(always)] pure fn sinh() -> Result { cast(f64::sinh(cast(*self))) }
#[inline(always)] pure fn radians() -> f32 { self * (f32::consts::pi / 180f32) } #[inline(always)] pure fn cosh() -> Result { cast(f64::cosh(cast(*self))) }
#[inline(always)] pure fn degrees() -> f32 { self * (180f32 / f32::consts::pi) } #[inline(always)] pure fn tanh() -> Result { cast(f64::tanh(cast(*self))) }
#[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)] pub pure fn sin<T:Trig <Result>, Result:NumCast>(angle: &T) -> Result { angle.sin() }
#[inline(always)] pure fn radians() -> f64 { self * (f64::consts::pi / 180f64) } #[inline(always)] pub pure fn cos<T:Trig <Result>, Result:NumCast>(angle: &T) -> Result { angle.cos() }
#[inline(always)] pure fn degrees() -> f64 { self * (180f64 / f64::consts::pi) } #[inline(always)] pub pure fn tan<T:Trig <Result>, Result:NumCast>(angle: &T) -> Result { angle.tan() }
#[inline(always)] pure fn sin() -> f64 { f64::sin(self) } #[inline(always)] pub pure fn asin<T:Trig<Result>, Result:NumCast>(x: &T) -> Result { x.asin() }
#[inline(always)] pure fn cos() -> f64 { f64::cos(self) } #[inline(always)] pub pure fn acos<T:Trig<Result>, Result:NumCast>(x: &T) -> Result { x.acos() }
#[inline(always)] pure fn tan() -> f64 { f64::tan(self) } #[inline(always)] pub pure fn atan<T:Trig<Result>, Result:NumCast>(x: &T) -> Result { x.atan() }
#[inline(always)] pure fn asin() -> f64 { f64::asin(self) } #[inline(always)] pub pure fn sinh<T:Trig<Result>, Result:NumCast>(x: &T) -> Result { x.sinh() }
#[inline(always)] pure fn acos() -> f64 { f64::acos(self) } #[inline(always)] pub pure fn cosh<T:Trig<Result>, Result:NumCast>(x: &T) -> Result { x.cosh() }
#[inline(always)] pure fn atan() -> f64 { f64::atan(self) } #[inline(always)] pub pure fn tanh<T:Trig<Result>, Result:NumCast>(x: &T) -> Result { x.tanh() }
#[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 { pub impl
#[inline(always)] pure fn radians() -> float { self * (float::consts::pi / 180f) } <
#[inline(always)] pure fn degrees() -> float { self * (180f / float::consts::pi) } ThetaT:Copy Trig<T>,
#[inline(always)] pure fn sin() -> float { cast(float::sin(cast(self))) } T:NumCast
#[inline(always)] pure fn cos() -> float { cast(float::cos(cast(self))) } >
#[inline(always)] pure fn tan() -> float { cast(float::tan(cast(self))) } Vec2<ThetaT>: Trig<Vec2<T>> {
#[inline(always)] pure fn asin() -> float { cast(float::asin(cast(self))) } #[inline(always)]
#[inline(always)] pure fn acos() -> float { cast(float::acos(cast(self))) } pure fn sin() -> Vec2<T> {
#[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<T:Copy Trig> Vec2<T>: Trig {
#[inline(always)] pure fn radians() -> Vec2<T> {
Vec2::new(radians(&self[0]),
radians(&self[1]))
}
#[inline(always)] pure fn degrees() -> Vec2<T> {
Vec2::new(degrees(&self[0]),
degrees(&self[1]))
}
#[inline(always)] pure fn sin() -> Vec2<T> {
Vec2::new(sin(&self[0]), Vec2::new(sin(&self[0]),
sin(&self[1])) sin(&self[1]))
} }
#[inline(always)] pure fn cos() -> Vec2<T> { #[inline(always)]
pure fn cos() -> Vec2<T> {
Vec2::new(cos(&self[0]), Vec2::new(cos(&self[0]),
cos(&self[1])) cos(&self[1]))
} }
#[inline(always)] pure fn tan() -> Vec2<T> { #[inline(always)]
pure fn tan() -> Vec2<T> {
Vec2::new(tan(&self[0]), Vec2::new(tan(&self[0]),
tan(&self[1])) tan(&self[1]))
} }
#[inline(always)] pure fn asin() -> Vec2<T> { #[inline(always)]
pure fn asin() -> Vec2<T> {
Vec2::new(asin(&self[0]), Vec2::new(asin(&self[0]),
asin(&self[1])) asin(&self[1]))
} }
#[inline(always)] pure fn acos() -> Vec2<T> { #[inline(always)]
pure fn acos() -> Vec2<T> {
Vec2::new(acos(&self[0]), Vec2::new(acos(&self[0]),
acos(&self[1])) acos(&self[1]))
} }
#[inline(always)] pure fn atan() -> Vec2<T> { #[inline(always)]
pure fn atan() -> Vec2<T> {
Vec2::new(atan(&self[0]), Vec2::new(atan(&self[0]),
atan(&self[1])) atan(&self[1]))
} }
#[inline(always)] pure fn sinh() -> Vec2<T> { #[inline(always)]
pure fn sinh() -> Vec2<T> {
Vec2::new(sinh(&self[0]), Vec2::new(sinh(&self[0]),
sinh(&self[1])) sinh(&self[1]))
} }
#[inline(always)] pure fn cosh() -> Vec2<T> { #[inline(always)]
pure fn cosh() -> Vec2<T> {
Vec2::new(cosh(&self[0]), Vec2::new(cosh(&self[0]),
cosh(&self[1])) cosh(&self[1]))
} }
#[inline(always)] pure fn tanh() -> Vec2<T> { #[inline(always)]
pure fn tanh() -> Vec2<T> {
Vec2::new(tanh(&self[0]), Vec2::new(tanh(&self[0]),
tanh(&self[1])) tanh(&self[1]))
} }
} }
pub impl<T:Copy Trig> Vec3<T>: Trig { pub impl
#[inline(always)] pure fn radians() -> Vec3<T> { <
Vec3::new(radians(&self[0]), ThetaT:Copy Trig<T>,
radians(&self[1]), T:NumCast
radians(&self[2])) >
} Vec3<ThetaT>: Trig<Vec3<T>> {
#[inline(always)]
#[inline(always)] pure fn degrees() -> Vec3<T> { pure fn sin() -> Vec3<T> {
Vec3::new(degrees(&self[0]),
degrees(&self[1]),
degrees(&self[2]))
}
#[inline(always)] pure fn sin() -> Vec3<T> {
Vec3::new(sin(&self[0]), Vec3::new(sin(&self[0]),
sin(&self[1]), sin(&self[1]),
sin(&self[2])) sin(&self[2]))
} }
#[inline(always)] pure fn cos() -> Vec3<T> { #[inline(always)]
pure fn cos() -> Vec3<T> {
Vec3::new(cos(&self[0]), Vec3::new(cos(&self[0]),
cos(&self[1]), cos(&self[1]),
cos(&self[2])) cos(&self[2]))
} }
#[inline(always)] pure fn tan() -> Vec3<T> { #[inline(always)]
pure fn tan() -> Vec3<T> {
Vec3::new(tan(&self[0]), Vec3::new(tan(&self[0]),
tan(&self[1]), tan(&self[1]),
tan(&self[2])) tan(&self[2]))
} }
#[inline(always)] pure fn asin() -> Vec3<T> { #[inline(always)]
pure fn asin() -> Vec3<T> {
Vec3::new(asin(&self[0]), Vec3::new(asin(&self[0]),
asin(&self[1]), asin(&self[1]),
asin(&self[2])) asin(&self[2]))
} }
#[inline(always)] pure fn acos() -> Vec3<T> { #[inline(always)]
pure fn acos() -> Vec3<T> {
Vec3::new(acos(&self[0]), Vec3::new(acos(&self[0]),
acos(&self[1]), acos(&self[1]),
acos(&self[2])) acos(&self[2]))
} }
#[inline(always)] pure fn atan() -> Vec3<T> { #[inline(always)]
pure fn atan() -> Vec3<T> {
Vec3::new(atan(&self[0]), Vec3::new(atan(&self[0]),
atan(&self[1]), atan(&self[1]),
atan(&self[2])) atan(&self[2]))
} }
#[inline(always)] pure fn sinh() -> Vec3<T> { #[inline(always)]
pure fn sinh() -> Vec3<T> {
Vec3::new(sinh(&self[0]), Vec3::new(sinh(&self[0]),
sinh(&self[1]), sinh(&self[1]),
sinh(&self[2])) sinh(&self[2]))
} }
#[inline(always)] pure fn cosh() -> Vec3<T> { #[inline(always)]
pure fn cosh() -> Vec3<T> {
Vec3::new(cosh(&self[0]), Vec3::new(cosh(&self[0]),
cosh(&self[1]), cosh(&self[1]),
cosh(&self[2])) cosh(&self[2]))
} }
#[inline(always)] pure fn tanh() -> Vec3<T> { #[inline(always)]
pure fn tanh() -> Vec3<T> {
Vec3::new(tanh(&self[0]), Vec3::new(tanh(&self[0]),
tanh(&self[1]), tanh(&self[1]),
tanh(&self[2])) tanh(&self[2]))
} }
} }
pub impl<T:Copy Trig> Vec4<T>: Trig { pub impl
#[inline(always)] pure fn radians() -> Vec4<T> { <
Vec4::new(radians(&self[0]), ThetaT:Copy Trig<T>,
radians(&self[1]), T:NumCast
radians(&self[2]), >
radians(&self[3])) Vec4<ThetaT>: Trig<Vec4<T>> {
} #[inline(always)]
pure fn sin() -> Vec4<T> {
#[inline(always)] pure fn degrees() -> Vec4<T> {
Vec4::new(degrees(&self[0]),
degrees(&self[1]),
degrees(&self[2]),
degrees(&self[3]))
}
#[inline(always)] pure fn sin() -> Vec4<T> {
Vec4::new(sin(&self[0]), Vec4::new(sin(&self[0]),
sin(&self[1]), sin(&self[1]),
sin(&self[2]), sin(&self[2]),
sin(&self[3])) sin(&self[3]))
} }
#[inline(always)] pure fn cos() -> Vec4<T> { #[inline(always)]
pure fn cos() -> Vec4<T> {
Vec4::new(cos(&self[0]), Vec4::new(cos(&self[0]),
cos(&self[1]), cos(&self[1]),
cos(&self[2]), cos(&self[2]),
cos(&self[3])) cos(&self[3]))
} }
#[inline(always)] pure fn tan() -> Vec4<T> { #[inline(always)]
pure fn tan() -> Vec4<T> {
Vec4::new(tan(&self[0]), Vec4::new(tan(&self[0]),
tan(&self[1]), tan(&self[1]),
tan(&self[2]), tan(&self[2]),
tan(&self[3])) tan(&self[3]))
} }
#[inline(always)] pure fn asin() -> Vec4<T> { #[inline(always)]
pure fn asin() -> Vec4<T> {
Vec4::new(asin(&self[0]), Vec4::new(asin(&self[0]),
asin(&self[1]), asin(&self[1]),
asin(&self[2]), asin(&self[2]),
asin(&self[3])) asin(&self[3]))
} }
#[inline(always)] pure fn acos() -> Vec4<T> { #[inline(always)]
pure fn acos() -> Vec4<T> {
Vec4::new(acos(&self[0]), Vec4::new(acos(&self[0]),
acos(&self[1]), acos(&self[1]),
acos(&self[2]), acos(&self[2]),
acos(&self[3])) acos(&self[3]))
} }
#[inline(always)] pure fn atan() -> Vec4<T> { #[inline(always)]
pure fn atan() -> Vec4<T> {
Vec4::new(atan(&self[0]), Vec4::new(atan(&self[0]),
atan(&self[1]), atan(&self[1]),
atan(&self[2]), atan(&self[2]),
atan(&self[3])) atan(&self[3]))
} }
#[inline(always)] pure fn sinh() -> Vec4<T> { #[inline(always)]
pure fn sinh() -> Vec4<T> {
Vec4::new(sinh(&self[0]), Vec4::new(sinh(&self[0]),
sinh(&self[1]), sinh(&self[1]),
sinh(&self[2]), sinh(&self[2]),
sinh(&self[3])) sinh(&self[3]))
} }
#[inline(always)] pure fn cosh() -> Vec4<T> { #[inline(always)]
pure fn cosh() -> Vec4<T> {
Vec4::new(cosh(&self[0]), Vec4::new(cosh(&self[0]),
cosh(&self[1]), cosh(&self[1]),
cosh(&self[2]), cosh(&self[2]),
cosh(&self[3])) cosh(&self[3]))
} }
#[inline(always)] pure fn tanh() -> Vec4<T> { #[inline(always)]
pure fn tanh() -> Vec4<T> {
Vec4::new(tanh(&self[0]), Vec4::new(tanh(&self[0]),
tanh(&self[1]), tanh(&self[1]),
tanh(&self[2]), tanh(&self[2]),