2012-11-26 06:23:34 +00:00
|
|
|
use core::cmp::{Eq, Ord};
|
2012-11-25 18:28:41 +00:00
|
|
|
use core::f64::consts::pi;
|
2012-11-26 07:31:02 +00:00
|
|
|
use funs::triganomic::{cos, sin};
|
|
|
|
use mat::{Mat3, Mat4};
|
|
|
|
use num::cast::{NumCast, cast};
|
|
|
|
use quat::Quat;
|
2012-11-25 16:26:01 +00:00
|
|
|
use vec::Vec3;
|
|
|
|
|
2012-11-26 07:31:02 +00:00
|
|
|
/**
|
|
|
|
* The base trait for anglular units
|
|
|
|
*/
|
2012-11-25 18:28:41 +00:00
|
|
|
pub trait Angle<T>: Add<self,self>
|
|
|
|
, Sub<self,self>
|
|
|
|
, Mul<T,self>
|
|
|
|
, Div<T,self>
|
|
|
|
, Modulo<T,self>
|
2012-11-26 06:23:34 +00:00
|
|
|
, Neg<self>
|
|
|
|
, Eq, Ord {
|
2012-11-27 02:34:15 +00:00
|
|
|
static pure fn full_rotation() -> self;
|
|
|
|
static pure fn half_rotation() -> self;
|
|
|
|
static pure fn quarter_rotation() -> self;
|
|
|
|
static pure fn eighth_rotation() -> self;
|
|
|
|
|
2012-11-25 18:28:41 +00:00
|
|
|
pure fn to_radians() -> Radians<T>;
|
|
|
|
pure fn to_degrees() -> Degrees<T>;
|
2012-11-25 16:26:01 +00:00
|
|
|
}
|
|
|
|
|
2012-11-25 18:28:41 +00:00
|
|
|
pub enum Radians<T> = T;
|
2012-11-25 17:43:48 +00:00
|
|
|
|
2012-11-25 18:28:41 +00:00
|
|
|
pub impl<T:Copy Num NumCast> Radians<T>: Angle<T> {
|
2012-11-27 02:34:15 +00:00
|
|
|
#[inline(always)] static pure fn full_rotation() -> Radians<T> { Radians(move cast(2.0 * pi)) }
|
|
|
|
#[inline(always)] static pure fn half_rotation() -> Radians<T> { Radians(move cast(pi)) }
|
|
|
|
#[inline(always)] static pure fn quarter_rotation() -> Radians<T> { Radians(move cast(pi / 2.0)) }
|
|
|
|
#[inline(always)] static pure fn eighth_rotation() -> Radians<T> { Radians(move cast(pi / 4.0)) }
|
|
|
|
|
2012-11-25 18:28:41 +00:00
|
|
|
#[inline(always)] pure fn to_radians() -> Radians<T> { self }
|
|
|
|
#[inline(always)] pure fn to_degrees() -> Degrees<T> { Degrees(*self * cast(180.0 / pi)) }
|
|
|
|
|
2012-11-26 06:04:32 +00:00
|
|
|
#[inline(always)] pure fn add(rhs: &Radians<T>) -> Radians<T> { Radians(*self + **rhs) }
|
|
|
|
#[inline(always)] pure fn sub(rhs: &Radians<T>) -> Radians<T> { Radians(*self - **rhs) }
|
|
|
|
#[inline(always)] pure fn mul(rhs: &T) -> Radians<T> { Radians(*self * *rhs) }
|
|
|
|
#[inline(always)] pure fn div(rhs: &T) -> Radians<T> { Radians(*self / *rhs) }
|
|
|
|
#[inline(always)] pure fn modulo(rhs: &T) -> Radians<T> { Radians(*self % *rhs) }
|
|
|
|
#[inline(always)] pure fn neg() -> Radians<T> { Radians(-*self) }
|
2012-11-25 17:43:48 +00:00
|
|
|
}
|
|
|
|
|
2012-11-26 06:23:34 +00:00
|
|
|
pub impl<T:Copy Eq> Radians<T>: Eq {
|
|
|
|
#[inline(always)] pure fn eq(other: &Radians<T>) -> bool { *self == **other }
|
|
|
|
#[inline(always)] pure fn ne(other: &Radians<T>) -> bool { *self != **other }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl<T:Copy Ord> Radians<T>: Ord {
|
|
|
|
#[inline(always)] pure fn lt(other: &Radians<T>) -> bool { *self < **other }
|
|
|
|
#[inline(always)] pure fn le(other: &Radians<T>) -> bool { *self <= **other }
|
|
|
|
#[inline(always)] pure fn ge(other: &Radians<T>) -> bool { *self >= **other }
|
|
|
|
#[inline(always)] pure fn gt(other: &Radians<T>) -> bool { *self > **other }
|
|
|
|
}
|
|
|
|
|
2012-11-25 18:28:41 +00:00
|
|
|
pub enum Degrees<T> = T;
|
2012-11-25 17:43:48 +00:00
|
|
|
|
2012-11-25 18:28:41 +00:00
|
|
|
pub impl<T:Copy Num NumCast> Degrees<T>: Angle<T> {
|
2012-11-27 02:34:15 +00:00
|
|
|
#[inline(always)] static pure fn full_rotation() -> Degrees<T> { Degrees(move cast(360.0)) }
|
|
|
|
#[inline(always)] static pure fn half_rotation() -> Degrees<T> { Degrees(move cast(180.0)) }
|
|
|
|
#[inline(always)] static pure fn quarter_rotation() -> Degrees<T> { Degrees(move cast(90.0)) }
|
|
|
|
#[inline(always)] static pure fn eighth_rotation() -> Degrees<T> { Degrees(move cast(45.0)) }
|
|
|
|
|
2012-11-25 18:28:41 +00:00
|
|
|
#[inline(always)] pure fn to_radians() -> Radians<T> { Radians(*self * cast(pi / 180.0)) }
|
|
|
|
#[inline(always)] pure fn to_degrees() -> Degrees<T> { self }
|
|
|
|
|
2012-11-26 06:04:32 +00:00
|
|
|
#[inline(always)] pure fn add(rhs: &Degrees<T>) -> Degrees<T> { Degrees(*self + **rhs) }
|
|
|
|
#[inline(always)] pure fn sub(rhs: &Degrees<T>) -> Degrees<T> { Degrees(*self - **rhs) }
|
|
|
|
#[inline(always)] pure fn mul(rhs: &T) -> Degrees<T> { Degrees(*self * *rhs) }
|
|
|
|
#[inline(always)] pure fn div(rhs: &T) -> Degrees<T> { Degrees(*self / *rhs) }
|
|
|
|
#[inline(always)] pure fn modulo(rhs: &T) -> Degrees<T> { Degrees(*self % *rhs) }
|
|
|
|
#[inline(always)] pure fn neg() -> Degrees<T> { Degrees(-*self) }
|
2012-11-25 17:43:48 +00:00
|
|
|
}
|
|
|
|
|
2012-11-26 06:23:34 +00:00
|
|
|
pub impl<T:Copy Eq> Degrees<T>: Eq {
|
|
|
|
#[inline(always)] pure fn eq(other: &Degrees<T>) -> bool { *self == **other }
|
|
|
|
#[inline(always)] pure fn ne(other: &Degrees<T>) -> bool { *self != **other }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub impl<T:Copy Ord> Degrees<T>: Ord {
|
|
|
|
#[inline(always)] pure fn lt(other: &Degrees<T>) -> bool { *self < **other }
|
|
|
|
#[inline(always)] pure fn le(other: &Degrees<T>) -> bool { *self <= **other }
|
|
|
|
#[inline(always)] pure fn ge(other: &Degrees<T>) -> bool { *self >= **other }
|
|
|
|
#[inline(always)] pure fn gt(other: &Degrees<T>) -> bool { *self > **other }
|
|
|
|
}
|
|
|
|
|
2012-11-26 07:31:02 +00:00
|
|
|
/**
|
|
|
|
* An angular rotation around an arbitary axis
|
|
|
|
*/
|
|
|
|
pub struct Rotation<T> {
|
2012-11-25 18:28:41 +00:00
|
|
|
theta: Radians<T>,
|
2012-11-26 23:48:01 +00:00
|
|
|
axis: Vec3<T>,
|
2012-11-25 16:26:01 +00:00
|
|
|
}
|
|
|
|
|
2012-11-26 07:31:02 +00:00
|
|
|
pub impl<T:Copy Num NumCast> Rotation<T> {
|
2012-11-26 23:48:01 +00:00
|
|
|
static pure fn new(theta: Radians<T>, axis: Vec3<T>) -> Rotation<T> {
|
|
|
|
Rotation { theta: move theta, axis: move axis }
|
|
|
|
}
|
|
|
|
|
2012-11-26 07:31:02 +00:00
|
|
|
pure fn to_mat3() -> Mat3<T> {
|
|
|
|
let c: T = cos(&self.theta);
|
|
|
|
let s: T = sin(&self.theta);
|
|
|
|
let _0: T = cast(0);
|
|
|
|
let _1: T = cast(1);
|
|
|
|
let t: T = _1 - c;
|
|
|
|
|
|
|
|
let x = self.axis.x;
|
|
|
|
let y = self.axis.y;
|
|
|
|
let z = self.axis.z;
|
|
|
|
|
|
|
|
Mat3::new(t * x * x + c, t * x * y + s * z, t * x * z - s * y,
|
|
|
|
t * x * y - s * z, t * y * y + c, t * y * z + s * x,
|
|
|
|
t * x * z - s - y, t * y * z - s * x, t * z * z + c)
|
|
|
|
}
|
|
|
|
|
|
|
|
pure fn to_mat4() -> Mat4<T> {
|
|
|
|
self.to_mat3().to_mat4()
|
|
|
|
}
|
|
|
|
|
|
|
|
pure fn to_quat() -> Quat<T> {
|
|
|
|
let half = self.theta / cast(2);
|
|
|
|
Quat::from_sv(cos(&half), self.axis.mul_t(sin(&half)))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-25 16:26:01 +00:00
|
|
|
pub struct Euler<T> {
|
2012-11-25 18:28:41 +00:00
|
|
|
x: Radians<T>, // pitch
|
|
|
|
y: Radians<T>, // yaw
|
|
|
|
z: Radians<T>, // roll
|
2012-11-25 16:26:01 +00:00
|
|
|
}
|