diff --git a/src/angle.rs b/src/angle.rs index c43a078..b487514 100644 --- a/src/angle.rs +++ b/src/angle.rs @@ -1,94 +1,52 @@ +use core::f64::consts::pi; use num::cast::*; use vec::Vec3; -pub enum Angle { - degrees(T), - radians(T), +pub trait Angle: Add + , Sub + , Mul + , Div + , Modulo + , Neg { + pure fn to_radians() -> Radians; + pure fn to_degrees() -> Degrees; } -pub impl Angle { - pure fn degrees() -> T { - match self { - degrees(theta) => theta, - radians(theta) => theta * cast(180f64 / f64::consts::pi) - } - } +pub enum Radians = T; + +pub impl Radians: Angle { + #[inline(always)] pure fn to_radians() -> Radians { self } + #[inline(always)] pure fn to_degrees() -> Degrees { Degrees(*self * cast(180.0 / pi)) } - pure fn radians() -> T { - match self { - degrees(theta) => theta * cast(f64::consts::pi / 180f64), - radians(theta) => theta - } - } + #[inline(always)] pure fn add(rhs: &Radians) -> Radians { self + *rhs } + #[inline(always)] pure fn sub(rhs: &Radians) -> Radians { self - *rhs } + #[inline(always)] pure fn mul(rhs: &T) -> Radians { self * *rhs } + #[inline(always)] pure fn div(rhs: &T) -> Radians { self / *rhs } + #[inline(always)] pure fn modulo(rhs: &T) -> Radians { self % *rhs } + #[inline(always)] pure fn neg() -> Radians {-self } } -pub impl Angle: Add> { - #[inline(always)] - pure fn add(rhs: &T) -> Angle { - match self { - degrees(theta) => degrees(theta + *rhs), - radians(theta) => radians(theta + *rhs) - } - } -} +pub enum Degrees = T; -pub impl Angle: Sub> { - #[inline(always)] - pure fn sub(rhs: &T) -> Angle { - match self { - degrees(theta) => degrees(theta - *rhs), - radians(theta) => radians(theta - *rhs) - } - } -} - -pub impl Angle: Mul> { - #[inline(always)] - pure fn mul(rhs: &T) -> Angle { - match self { - degrees(theta) => degrees(theta * *rhs), - radians(theta) => radians(theta * *rhs) - } - } -} - -pub impl Angle: Div> { - #[inline(always)] - pure fn div(rhs: &T) -> Angle { - match self { - degrees(theta) => degrees(theta / *rhs), - radians(theta) => radians(theta / *rhs) - } - } -} - -pub impl Angle: Modulo> { - #[inline(always)] - pure fn modulo(rhs: &T) -> Angle { - match self { - degrees(theta) => degrees(theta % *rhs), - radians(theta) => radians(theta % *rhs) - } - } -} - -pub impl Angle: Neg> { - #[inline(always)] - pure fn neg() -> Angle { - match self { - degrees(theta) => degrees(-theta), - radians(theta) => radians(-theta) - } - } +pub impl Degrees: Angle { + #[inline(always)] pure fn to_radians() -> Radians { Radians(*self * cast(pi / 180.0)) } + #[inline(always)] pure fn to_degrees() -> Degrees { self } + + #[inline(always)] pure fn add(rhs: &Degrees) -> Degrees { self + *rhs } + #[inline(always)] pure fn sub(rhs: &Degrees) -> Degrees { self - *rhs } + #[inline(always)] pure fn mul(rhs: &T) -> Degrees { self * *rhs } + #[inline(always)] pure fn div(rhs: &T) -> Degrees { self / *rhs } + #[inline(always)] pure fn modulo(rhs: &T) -> Degrees { self % *rhs } + #[inline(always)] pure fn neg() -> Degrees {-self } } pub struct AxisRotation { axis: Vec3, - theta: Angle, + theta: Radians, } pub struct Euler { - x: T, // pitch - y: T, // yaw - z: T, // roll + x: Radians, // pitch + y: Radians, // yaw + z: Radians, // roll } \ No newline at end of file diff --git a/src/funs/projection.rs b/src/funs/projection.rs index 1240895..7ec9e7f 100644 --- a/src/funs/projection.rs +++ b/src/funs/projection.rs @@ -12,7 +12,7 @@ use num::ext::FloatExt; // http://www.opengl.org/wiki/GluPerspective_code // #[inline(always)] -pure fn perspective(fovy: Angle, aspectRatio: T, near: T, far: T) -> Mat4 { +pure fn perspective(fovy: Radians, aspectRatio: T, near: T, far: T) -> Mat4 { let ymax = near * tan(&fovy); let xmax = ymax * aspectRatio; return frustum(-xmax, xmax, -ymax, ymax, near, far); diff --git a/src/funs/test/test_transform.rs b/src/funs/test/test_transform.rs index 9b0b9e1..907ec5c 100644 --- a/src/funs/test/test_transform.rs +++ b/src/funs/test/test_transform.rs @@ -1,5 +1,5 @@ use funs::transform::*; -use angle::degrees; +use angle::Degrees; use mat::Mat4; use vec::{Vec3, Vec4}; @@ -8,7 +8,7 @@ fn test_mat4_from_rotation() { { let pos = Vec4::new(1f32, 0f32, 0f32, 1f32); // let tform = mat4_from_rotation(180f32, Vec3::unit_z()); - let tform = mat4_from_rotation(degrees(180f32), Vec3::new(0f32, 0f32, 1f32)); + let tform = mat4_from_rotation(Degrees(180f32).to_radians(), Vec3::new(0f32, 0f32, 1f32)); let newpos = tform.mul_v(&pos); let expected = Vec4::new(-1f32, 0f32, 0f32, 1f32); @@ -20,8 +20,8 @@ fn test_mat4_from_rotation() { // let tform_a = mat4_from_rotation(90f32, Vec3::unit_y()); // let tform_b = mat4_from_rotation(90f32, -Vec3::unit_y()); - let tform_a = mat4_from_rotation(degrees(90f32), Vec3::new(0f32, 1f32, 0f32)); - let tform_b = mat4_from_rotation(degrees(90f32), -Vec3::new(0f32, 1f32, 0f32)); + let tform_a = mat4_from_rotation(Degrees(90f32).to_radians(), Vec3::new(0f32, 1f32, 0f32)); + let tform_b = mat4_from_rotation(Degrees(90f32).to_radians(), -Vec3::new(0f32, 1f32, 0f32)); let newpos_a = tform_a.mul_v(&pos); let newpos_b = tform_b.mul_v(&pos); diff --git a/src/funs/transform.rs b/src/funs/transform.rs index f818091..7eb35a8 100644 --- a/src/funs/transform.rs +++ b/src/funs/transform.rs @@ -3,7 +3,7 @@ use angle::Angle; use mat::{Mat3, Mat4}; use num::cast::*; -pub pure fn mat3_from_rotation(theta: Angle, axis: Vec3) -> Mat3 { +pub pure fn mat3_from_rotation(theta: Radians, axis: Vec3) -> Mat3 { let c: T = cos(&theta); let s: T = sin(&theta); let _0: T = cast(0); @@ -15,6 +15,6 @@ pub pure fn mat3_from_rotation(theta: Angle, axis: Vec3(theta: Angle, axis: Vec3) -> Mat4 { +pub pure fn mat4_from_rotation(theta: Radians, axis: Vec3) -> Mat4 { mat3_from_rotation(theta, axis).to_mat4() } \ No newline at end of file diff --git a/src/funs/trig.rs b/src/funs/trig.rs index 55d8e7a..0dd2acf 100644 --- a/src/funs/trig.rs +++ b/src/funs/trig.rs @@ -17,10 +17,10 @@ priv trait Trig { #[inline(always)] pub pure fn cos, R>(theta: &T) -> R { theta.cos() } #[inline(always)] pub pure fn tan, R>(theta: &T) -> R { theta.tan() } -priv impl Angle: Trig { - #[inline(always)] pure fn sin() -> T { cast(f64::sin(cast(self.radians()))) } - #[inline(always)] pure fn cos() -> T { cast(f64::cos(cast(self.radians()))) } - #[inline(always)] pure fn tan() -> T { cast(f64::tan(cast(self.radians()))) } +priv impl Radians: Trig { + #[inline(always)] pure fn sin() -> T { cast(f64::sin(cast(*self))) } + #[inline(always)] pure fn cos() -> T { cast(f64::cos(cast(*self))) } + #[inline(always)] pure fn tan() -> T { cast(f64::tan(cast(*self))) } } /// @@ -29,31 +29,31 @@ priv impl Angle: Trig { /// http://en.wikipedia.org/wiki/Inverse_trigonometric_functions /// pub trait InvTrig { - pure fn asin() -> Angle; - pure fn acos() -> Angle; - pure fn atan() -> Angle; + pure fn asin() -> Radians; + pure fn acos() -> Radians; + pure fn atan() -> Radians; } -#[inline(always)] pub pure fn asin(x: &T) -> Angle { x.asin() } -#[inline(always)] pub pure fn acos(x: &T) -> Angle { x.acos() } -#[inline(always)] pub pure fn atan(x: &T) -> Angle { x.atan() } +#[inline(always)] pub pure fn asin(x: &T) -> Radians { x.asin() } +#[inline(always)] pub pure fn acos(x: &T) -> Radians { x.acos() } +#[inline(always)] pub pure fn atan(x: &T) -> Radians { x.atan() } pub impl f32: InvTrig { - #[inline(always)] pure fn asin() -> Angle { radians(f32::asin(self)) } - #[inline(always)] pure fn acos() -> Angle { radians(f32::acos(self)) } - #[inline(always)] pure fn atan() -> Angle { radians(f32::atan(self)) } + #[inline(always)] pure fn asin() -> Radians { Radians(f32::asin(self)) } + #[inline(always)] pure fn acos() -> Radians { Radians(f32::acos(self)) } + #[inline(always)] pure fn atan() -> Radians { Radians(f32::atan(self)) } } pub impl f64: InvTrig { - #[inline(always)] pure fn asin() -> Angle { radians(f64::asin(self)) } - #[inline(always)] pure fn acos() -> Angle { radians(f64::acos(self)) } - #[inline(always)] pure fn atan() -> Angle { radians(f64::atan(self)) } + #[inline(always)] pure fn asin() -> Radians { Radians(f64::asin(self)) } + #[inline(always)] pure fn acos() -> Radians { Radians(f64::acos(self)) } + #[inline(always)] pure fn atan() -> Radians { Radians(f64::atan(self)) } } pub impl float: InvTrig { - #[inline(always)] pure fn asin() -> Angle { radians(f64::asin(cast(self)).to_float()) } - #[inline(always)] pure fn acos() -> Angle { radians(f64::acos(cast(self)).to_float()) } - #[inline(always)] pure fn atan() -> Angle { radians(f64::atan(cast(self)).to_float()) } + #[inline(always)] pure fn asin() -> Radians { Radians(f64::asin(cast(self)).to_float()) } + #[inline(always)] pure fn acos() -> Radians { Radians(f64::acos(cast(self)).to_float()) } + #[inline(always)] pure fn atan() -> Radians { Radians(f64::atan(cast(self)).to_float()) } } /// diff --git a/src/quat.rs b/src/quat.rs index 840342b..8b66969 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -222,7 +222,7 @@ pub impl Quat: Quaternion { } #[inline(always)] - pub pure fn from_axis_angle(axis: Vec3, theta: Angle) -> Quat { + pub pure fn from_axis_angle(axis: Vec3, theta: Radians) -> Quat { let half = theta / cast(2); Quat::from_sv(cos(&half), axis.mul_t(sin(&half))) }