Divide Angle enum into separate Radians and Degrees types
This commit is contained in:
parent
eda42604b7
commit
5393e9a1f6
6 changed files with 62 additions and 104 deletions
112
src/angle.rs
112
src/angle.rs
|
@ -1,94 +1,52 @@
|
||||||
|
use core::f64::consts::pi;
|
||||||
use num::cast::*;
|
use num::cast::*;
|
||||||
use vec::Vec3;
|
use vec::Vec3;
|
||||||
|
|
||||||
pub enum Angle<T> {
|
pub trait Angle<T>: Add<self,self>
|
||||||
degrees(T),
|
, Sub<self,self>
|
||||||
radians(T),
|
, Mul<T,self>
|
||||||
|
, Div<T,self>
|
||||||
|
, Modulo<T,self>
|
||||||
|
, Neg<self> {
|
||||||
|
pure fn to_radians() -> Radians<T>;
|
||||||
|
pure fn to_degrees() -> Degrees<T>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<T:Copy Num NumCast> Angle<T> {
|
pub enum Radians<T> = T;
|
||||||
pure fn degrees() -> T {
|
|
||||||
match self {
|
pub impl<T:Copy Num NumCast> Radians<T>: Angle<T> {
|
||||||
degrees(theta) => theta,
|
#[inline(always)] pure fn to_radians() -> Radians<T> { self }
|
||||||
radians(theta) => theta * cast(180f64 / f64::consts::pi)
|
#[inline(always)] pure fn to_degrees() -> Degrees<T> { Degrees(*self * cast(180.0 / pi)) }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pure fn radians() -> T {
|
#[inline(always)] pure fn add(rhs: &Radians<T>) -> Radians<T> { self + *rhs }
|
||||||
match self {
|
#[inline(always)] pure fn sub(rhs: &Radians<T>) -> Radians<T> { self - *rhs }
|
||||||
degrees(theta) => theta * cast(f64::consts::pi / 180f64),
|
#[inline(always)] pure fn mul(rhs: &T) -> Radians<T> { self * *rhs }
|
||||||
radians(theta) => theta
|
#[inline(always)] pure fn div(rhs: &T) -> Radians<T> { self / *rhs }
|
||||||
}
|
#[inline(always)] pure fn modulo(rhs: &T) -> Radians<T> { self % *rhs }
|
||||||
}
|
#[inline(always)] pure fn neg() -> Radians<T> {-self }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl<T:Copy Num> Angle<T>: Add<T,Angle<T>> {
|
pub enum Degrees<T> = T;
|
||||||
#[inline(always)]
|
|
||||||
pure fn add(rhs: &T) -> Angle<T> {
|
|
||||||
match self {
|
|
||||||
degrees(theta) => degrees(theta + *rhs),
|
|
||||||
radians(theta) => radians(theta + *rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl<T:Copy Num> Angle<T>: Sub<T,Angle<T>> {
|
pub impl<T:Copy Num NumCast> Degrees<T>: Angle<T> {
|
||||||
#[inline(always)]
|
#[inline(always)] pure fn to_radians() -> Radians<T> { Radians(*self * cast(pi / 180.0)) }
|
||||||
pure fn sub(rhs: &T) -> Angle<T> {
|
#[inline(always)] pure fn to_degrees() -> Degrees<T> { self }
|
||||||
match self {
|
|
||||||
degrees(theta) => degrees(theta - *rhs),
|
#[inline(always)] pure fn add(rhs: &Degrees<T>) -> Degrees<T> { self + *rhs }
|
||||||
radians(theta) => radians(theta - *rhs)
|
#[inline(always)] pure fn sub(rhs: &Degrees<T>) -> Degrees<T> { self - *rhs }
|
||||||
}
|
#[inline(always)] pure fn mul(rhs: &T) -> Degrees<T> { self * *rhs }
|
||||||
}
|
#[inline(always)] pure fn div(rhs: &T) -> Degrees<T> { self / *rhs }
|
||||||
}
|
#[inline(always)] pure fn modulo(rhs: &T) -> Degrees<T> { self % *rhs }
|
||||||
|
#[inline(always)] pure fn neg() -> Degrees<T> {-self }
|
||||||
pub impl<T:Copy Num> Angle<T>: Mul<T,Angle<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pure fn mul(rhs: &T) -> Angle<T> {
|
|
||||||
match self {
|
|
||||||
degrees(theta) => degrees(theta * *rhs),
|
|
||||||
radians(theta) => radians(theta * *rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl<T:Copy Num> Angle<T>: Div<T,Angle<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pure fn div(rhs: &T) -> Angle<T> {
|
|
||||||
match self {
|
|
||||||
degrees(theta) => degrees(theta / *rhs),
|
|
||||||
radians(theta) => radians(theta / *rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl<T:Copy Num> Angle<T>: Modulo<T,Angle<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pure fn modulo(rhs: &T) -> Angle<T> {
|
|
||||||
match self {
|
|
||||||
degrees(theta) => degrees(theta % *rhs),
|
|
||||||
radians(theta) => radians(theta % *rhs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub impl<T:Copy Num> Angle<T>: Neg<Angle<T>> {
|
|
||||||
#[inline(always)]
|
|
||||||
pure fn neg() -> Angle<T> {
|
|
||||||
match self {
|
|
||||||
degrees(theta) => degrees(-theta),
|
|
||||||
radians(theta) => radians(-theta)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AxisRotation<T> {
|
pub struct AxisRotation<T> {
|
||||||
axis: Vec3<T>,
|
axis: Vec3<T>,
|
||||||
theta: Angle<T>,
|
theta: Radians<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Euler<T> {
|
pub struct Euler<T> {
|
||||||
x: T, // pitch
|
x: Radians<T>, // pitch
|
||||||
y: T, // yaw
|
y: Radians<T>, // yaw
|
||||||
z: T, // roll
|
z: Radians<T>, // roll
|
||||||
}
|
}
|
|
@ -12,7 +12,7 @@ use num::ext::FloatExt;
|
||||||
// http://www.opengl.org/wiki/GluPerspective_code
|
// http://www.opengl.org/wiki/GluPerspective_code
|
||||||
//
|
//
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pure fn perspective<T:Copy FloatExt>(fovy: Angle<T>, aspectRatio: T, near: T, far: T) -> Mat4<T> {
|
pure fn perspective<T:Copy FloatExt>(fovy: Radians<T>, aspectRatio: T, near: T, far: T) -> Mat4<T> {
|
||||||
let ymax = near * tan(&fovy);
|
let ymax = near * tan(&fovy);
|
||||||
let xmax = ymax * aspectRatio;
|
let xmax = ymax * aspectRatio;
|
||||||
return frustum(-xmax, xmax, -ymax, ymax, near, far);
|
return frustum(-xmax, xmax, -ymax, ymax, near, far);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use funs::transform::*;
|
use funs::transform::*;
|
||||||
use angle::degrees;
|
use angle::Degrees;
|
||||||
use mat::Mat4;
|
use mat::Mat4;
|
||||||
use vec::{Vec3, Vec4};
|
use vec::{Vec3, Vec4};
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ fn test_mat4_from_rotation() {
|
||||||
{
|
{
|
||||||
let pos = Vec4::new(1f32, 0f32, 0f32, 1f32);
|
let pos = Vec4::new(1f32, 0f32, 0f32, 1f32);
|
||||||
// let tform = mat4_from_rotation(180f32, Vec3::unit_z());
|
// 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 newpos = tform.mul_v(&pos);
|
||||||
|
|
||||||
let expected = Vec4::new(-1f32, 0f32, 0f32, 1f32);
|
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_a = mat4_from_rotation(90f32, Vec3::unit_y());
|
||||||
// let tform_b = 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_a = mat4_from_rotation(Degrees(90f32).to_radians(), Vec3::new(0f32, 1f32, 0f32));
|
||||||
let tform_b = mat4_from_rotation(degrees(90f32), -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_a = tform_a.mul_v(&pos);
|
||||||
let newpos_b = tform_b.mul_v(&pos);
|
let newpos_b = tform_b.mul_v(&pos);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ use angle::Angle;
|
||||||
use mat::{Mat3, Mat4};
|
use mat::{Mat3, Mat4};
|
||||||
use num::cast::*;
|
use num::cast::*;
|
||||||
|
|
||||||
pub pure fn mat3_from_rotation<T:Copy Num NumCast>(theta: Angle<T>, axis: Vec3<T>) -> Mat3<T> {
|
pub pure fn mat3_from_rotation<T:Copy Num NumCast>(theta: Radians<T>, axis: Vec3<T>) -> Mat3<T> {
|
||||||
let c: T = cos(&theta);
|
let c: T = cos(&theta);
|
||||||
let s: T = sin(&theta);
|
let s: T = sin(&theta);
|
||||||
let _0: T = cast(0);
|
let _0: T = cast(0);
|
||||||
|
@ -15,6 +15,6 @@ pub pure fn mat3_from_rotation<T:Copy Num NumCast>(theta: Angle<T>, axis: Vec3<T
|
||||||
t * axis.x * axis.z - s - axis.y, t * axis.y * axis.z - s * axis.x, t * axis.z * axis.z + c)
|
t * axis.x * axis.z - s - axis.y, t * axis.y * axis.z - s * axis.x, t * axis.z * axis.z + c)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub pure fn mat4_from_rotation<T:Copy Num NumCast>(theta: Angle<T>, axis: Vec3<T>) -> Mat4<T> {
|
pub pure fn mat4_from_rotation<T:Copy Num NumCast>(theta: Radians<T>, axis: Vec3<T>) -> Mat4<T> {
|
||||||
mat3_from_rotation(theta, axis).to_mat4()
|
mat3_from_rotation(theta, axis).to_mat4()
|
||||||
}
|
}
|
|
@ -17,10 +17,10 @@ priv trait Trig<T> {
|
||||||
#[inline(always)] pub pure fn cos<T:Trig<R>, R>(theta: &T) -> R { theta.cos() }
|
#[inline(always)] pub pure fn cos<T:Trig<R>, R>(theta: &T) -> R { theta.cos() }
|
||||||
#[inline(always)] pub pure fn tan<T:Trig<R>, R>(theta: &T) -> R { theta.tan() }
|
#[inline(always)] pub pure fn tan<T:Trig<R>, R>(theta: &T) -> R { theta.tan() }
|
||||||
|
|
||||||
priv impl<T:Copy Num NumCast> Angle<T>: Trig<T> {
|
priv impl<T:Copy Num NumCast> Radians<T>: Trig<T> {
|
||||||
#[inline(always)] pure fn sin() -> T { cast(f64::sin(cast(self.radians()))) }
|
#[inline(always)] pure fn sin() -> T { cast(f64::sin(cast(*self))) }
|
||||||
#[inline(always)] pure fn cos() -> T { cast(f64::cos(cast(self.radians()))) }
|
#[inline(always)] pure fn cos() -> T { cast(f64::cos(cast(*self))) }
|
||||||
#[inline(always)] pure fn tan() -> T { cast(f64::tan(cast(self.radians()))) }
|
#[inline(always)] pure fn tan() -> T { cast(f64::tan(cast(*self))) }
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
@ -29,31 +29,31 @@ priv impl<T:Copy Num NumCast> Angle<T>: Trig<T> {
|
||||||
/// http://en.wikipedia.org/wiki/Inverse_trigonometric_functions
|
/// http://en.wikipedia.org/wiki/Inverse_trigonometric_functions
|
||||||
///
|
///
|
||||||
pub trait InvTrig {
|
pub trait InvTrig {
|
||||||
pure fn asin() -> Angle<self>;
|
pure fn asin() -> Radians<self>;
|
||||||
pure fn acos() -> Angle<self>;
|
pure fn acos() -> Radians<self>;
|
||||||
pure fn atan() -> Angle<self>;
|
pure fn atan() -> Radians<self>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] pub pure fn asin<T:InvTrig>(x: &T) -> Angle<T> { x.asin() }
|
#[inline(always)] pub pure fn asin<T:InvTrig>(x: &T) -> Radians<T> { x.asin() }
|
||||||
#[inline(always)] pub pure fn acos<T:InvTrig>(x: &T) -> Angle<T> { x.acos() }
|
#[inline(always)] pub pure fn acos<T:InvTrig>(x: &T) -> Radians<T> { x.acos() }
|
||||||
#[inline(always)] pub pure fn atan<T:InvTrig>(x: &T) -> Angle<T> { x.atan() }
|
#[inline(always)] pub pure fn atan<T:InvTrig>(x: &T) -> Radians<T> { x.atan() }
|
||||||
|
|
||||||
pub impl f32: InvTrig {
|
pub impl f32: InvTrig {
|
||||||
#[inline(always)] pure fn asin() -> Angle<f32> { radians(f32::asin(self)) }
|
#[inline(always)] pure fn asin() -> Radians<f32> { Radians(f32::asin(self)) }
|
||||||
#[inline(always)] pure fn acos() -> Angle<f32> { radians(f32::acos(self)) }
|
#[inline(always)] pure fn acos() -> Radians<f32> { Radians(f32::acos(self)) }
|
||||||
#[inline(always)] pure fn atan() -> Angle<f32> { radians(f32::atan(self)) }
|
#[inline(always)] pure fn atan() -> Radians<f32> { Radians(f32::atan(self)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl f64: InvTrig {
|
pub impl f64: InvTrig {
|
||||||
#[inline(always)] pure fn asin() -> Angle<f64> { radians(f64::asin(self)) }
|
#[inline(always)] pure fn asin() -> Radians<f64> { Radians(f64::asin(self)) }
|
||||||
#[inline(always)] pure fn acos() -> Angle<f64> { radians(f64::acos(self)) }
|
#[inline(always)] pure fn acos() -> Radians<f64> { Radians(f64::acos(self)) }
|
||||||
#[inline(always)] pure fn atan() -> Angle<f64> { radians(f64::atan(self)) }
|
#[inline(always)] pure fn atan() -> Radians<f64> { Radians(f64::atan(self)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub impl float: InvTrig {
|
pub impl float: InvTrig {
|
||||||
#[inline(always)] pure fn asin() -> Angle<float> { radians(f64::asin(cast(self)).to_float()) }
|
#[inline(always)] pure fn asin() -> Radians<float> { Radians(f64::asin(cast(self)).to_float()) }
|
||||||
#[inline(always)] pure fn acos() -> Angle<float> { radians(f64::acos(cast(self)).to_float()) }
|
#[inline(always)] pure fn acos() -> Radians<float> { Radians(f64::acos(cast(self)).to_float()) }
|
||||||
#[inline(always)] pure fn atan() -> Angle<float> { radians(f64::atan(cast(self)).to_float()) }
|
#[inline(always)] pure fn atan() -> Radians<float> { Radians(f64::atan(cast(self)).to_float()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
|
@ -222,7 +222,7 @@ pub impl<T:Copy Num NumCast Exp Clamp Ord InvTrig> Quat<T>: Quaternion<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub pure fn from_axis_angle(axis: Vec3<T>, theta: Angle<T>) -> Quat<T> {
|
pub pure fn from_axis_angle(axis: Vec3<T>, theta: Radians<T>) -> Quat<T> {
|
||||||
let half = theta / cast(2);
|
let half = theta / cast(2);
|
||||||
Quat::from_sv(cos(&half), axis.mul_t(sin(&half)))
|
Quat::from_sv(cos(&half), axis.mul_t(sin(&half)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue