Implement common functions for angle types

This commit is contained in:
Brendan Zabarauskas 2012-11-29 15:39:55 +10:00
parent 8e7ae0d4ae
commit 60388118d2
2 changed files with 128 additions and 0 deletions

View file

@ -6,6 +6,7 @@
*/
use num::cast::cast;
use angle::{Radians, Degrees};
use vec::{Vec2, Vec3, Vec4};
pub trait Sign {
@ -57,6 +58,17 @@ pub impl float: Sign {
}
pub impl<T:Copy Sign> Radians<T>: Sign{
#[inline(always)] pure fn abs() -> Radians<T> { Radians(abs(&*self)) }
#[inline(always)] pure fn sign() -> Radians<T> { Radians(sign(&*self)) }
}
pub impl<T:Copy Sign> Degrees<T>: Sign{
#[inline(always)] pure fn abs() -> Degrees<T> { Degrees(abs(&*self)) }
#[inline(always)] pure fn sign() -> Degrees<T> { Degrees(sign(&*self)) }
}
pub impl<T:Copy Sign> Vec2<T>: Sign {
#[inline(always)]
@ -149,6 +161,26 @@ pub impl float: Approx {
#[inline(always)] pure fn fract() -> float { self - floor(&self) }
}
pub impl<T:Copy Approx> Radians<T>: Approx{
#[inline(always)] pure fn floor() -> Radians<T> { Radians(floor(&*self)) }
#[inline(always)] pure fn trunc() -> Radians<T> { Radians(trunc(&*self)) }
#[inline(always)] pure fn round() -> Radians<T> { Radians(round(&*self)) }
// #[inline(always)] pure fn roundEven() -> Radians<T> { Radians(roundEven(&*self)) }
#[inline(always)] pure fn ceil() -> Radians<T> { Radians(ceil(&*self)) }
#[inline(always)] pure fn fract() -> Radians<T> { Radians(fract(&*self)) }
}
pub impl<T:Copy Approx> Degrees<T>: Approx{
#[inline(always)] pure fn floor() -> Degrees<T> { Degrees(floor(&*self)) }
#[inline(always)] pure fn trunc() -> Degrees<T> { Degrees(trunc(&*self)) }
#[inline(always)] pure fn round() -> Degrees<T> { Degrees(round(&*self)) }
// #[inline(always)] pure fn roundEven() -> Degrees<T> { Degrees(roundEven(&*self)) }
#[inline(always)] pure fn ceil() -> Degrees<T> { Degrees(ceil(&*self)) }
#[inline(always)] pure fn fract() -> Degrees<T> { Degrees(fract(&*self)) }
}
pub impl<T:Copy Approx> Vec2<T>: Approx {
#[inline(always)]
pure fn floor() -> Vec2<T> {
@ -357,6 +389,18 @@ pub impl float: MinMax {
#[inline(always)] pure fn max(other: &float) -> float { if self > *other { self } else { *other } }
}
pub impl<T:Copy MinMax> Radians<T>: MinMax{
#[inline(always)] pure fn min(other: &Radians<T>) -> Radians<T> { Radians(min(&*self, &**other)) }
#[inline(always)] pure fn max(other: &Radians<T>) -> Radians<T> { Radians(max(&*self, &**other)) }
}
pub impl<T:Copy MinMax> Degrees<T>: MinMax{
#[inline(always)] pure fn min(other: &Degrees<T>) -> Degrees<T> { Degrees(min(&*self, &**other)) }
#[inline(always)] pure fn max(other: &Degrees<T>) -> Degrees<T> { Degrees(max(&*self, &**other)) }
}
pub impl<T:Copy MinMax> Vec2<T>: MinMax {
#[inline(always)]
pure fn min(other: &Vec2<T>) -> Vec2<T> {
@ -425,6 +469,22 @@ pub impl f32: Clamp { #[inline(always)] pure fn clamp(mn: &f32, mx: &f32)
pub impl f64: Clamp { #[inline(always)] pure fn clamp(mn: &f64, mx: &f64) -> f64 { min(&max(&self, mn), mx) } }
pub impl float: Clamp { #[inline(always)] pure fn clamp(mn: &float, mx: &float) -> float { min(&max(&self, mn), mx) } }
pub impl<T:Clamp> Radians<T>: Clamp {
#[inline(always)]
pure fn clamp(mn: &Radians<T>, mx: &Radians<T>) -> Radians<T> {
Radians((*self).clamp(&**mn, &**mx))
}
}
pub impl<T:Clamp> Degrees<T>: Clamp {
#[inline(always)]
pure fn clamp(mn: &Degrees<T>, mx: &Degrees<T>) -> Degrees<T> {
Degrees((*self).clamp(&**mn, &**mx))
}
}
pub impl<T:Copy Clamp> Vec2<T>: Clamp {
#[inline(always)]
pure fn clamp(mn: &Vec2<T>, mx: &Vec2<T>) -> Vec2<T> {
@ -516,6 +576,25 @@ pub impl float: Mix {
}
}
pub impl<T:Mix> Radians<T>: Mix {
#[inline(always)]
pure fn mix(other: &Radians<T>, value: &Radians<T>) -> Radians<T> {
Radians((*self).mix(&**other, &**value))
}
#[inline(always)]
pure fn smooth_step(edge0: &Radians<T>, edge1: &Radians<T>) -> Radians<T> {
Radians((*self).smooth_step(&**edge0, &**edge1))
}
#[inline(always)]
pure fn step(edge: &Radians<T>) -> Radians<T> {
Radians((*self).step(&**edge))
}
}
pub impl<T:Copy Mix> Vec2<T>: Mix {
#[inline(always)]
pure fn mix(other: &Vec2<T>, value: &Vec2<T>) -> Vec2<T> {

View file

@ -1,4 +1,5 @@
use common::*;
use angle::{Radians, Degrees};
use vec::{Vec2, Vec3, Vec4};
#[test]
@ -16,6 +17,20 @@ fn test_abs() {
assert abs(&0.0) == 0.0;
assert abs(&2.5) == 2.5;
assert abs(&-2.5) == 2.5;
assert Radians(0.0).abs() == Radians(0.0);
assert Radians(2.5).abs() == Radians(2.5);
assert (Radians(-2.5)).abs() == Radians(2.5);
assert abs(&Radians(0.0)) == Radians(0.0);
assert abs(&Radians(2.5)) == Radians(2.5);
assert abs(&Radians(-2.5)) == Radians(2.5);
assert Degrees(0.0).abs() == Degrees(0.0);
assert Degrees(2.5).abs() == Degrees(2.5);
assert (Degrees(-2.5)).abs() == Degrees(2.5);
assert abs(&Degrees(0.0)) == Degrees(0.0);
assert abs(&Degrees(2.5)) == Degrees(2.5);
assert abs(&Degrees(-2.5)) == Degrees(2.5);
}
#[test]
@ -33,6 +48,20 @@ fn test_sign() {
assert sign(&0.0) == 0.0;
assert sign(&2.5) == 1.0;
assert sign(&-2.5) == -1.0;
assert Radians(0.0).sign() == Radians(0.0);
assert Radians(2.5).sign() == Radians(1.0);
assert (Radians(-2.5)).sign()== Radians(-1.0);
assert sign(&Radians(0.0)) == Radians(0.0);
assert sign(&Radians(2.5)) == Radians(1.0);
assert sign(&Radians(-2.5)) == Radians(-1.0);
assert Degrees(0.0).sign() == Degrees(0.0);
assert Degrees(2.5).sign() == Degrees(1.0);
assert (Degrees(-2.5)).sign()== Degrees(-1.0);
assert sign(&Degrees(0.0)) == Degrees(0.0);
assert sign(&Degrees(2.5)) == Degrees(1.0);
assert sign(&Degrees(-2.5)) == Degrees(-1.0);
}
#[test]
@ -93,6 +122,16 @@ fn test_min() {
assert min(&2f32, &1f32) == 1f32;
assert min(&2f64, &1f64) == 1f64;
assert Radians(1).min(&Radians(2)) == Radians(1);
assert Radians(2).min(&Radians(1)) == Radians(1);
assert min(&Radians(1), &Radians(2)) == Radians(1);
assert min(&Radians(2), &Radians(1)) == Radians(1);
assert Degrees(1).min(&Degrees(2)) == Degrees(1);
assert Degrees(2).min(&Degrees(1)) == Degrees(1);
assert min(&Degrees(1), &Degrees(2)) == Degrees(1);
assert min(&Degrees(2), &Degrees(1)) == Degrees(1);
assert min(&Vec2::new(1, 2), &Vec2::new(2, 1)) == Vec2::new(1, 1);
assert min(&Vec3::new(1, 2, 3), &Vec3::new(3, 2, 1)) == Vec3::new(1, 2, 1);
assert min(&Vec4::new(1, 2, 3, 4), &Vec4::new(4, 3, 2, 1)) == Vec4::new(1, 2, 2, 1);
@ -162,6 +201,16 @@ fn test_max() {
assert max(&2f32, &1f32) == 2f32;
assert max(&2f64, &1f64) == 2f64;
assert Radians(1).max(&Radians(2)) == Radians(2);
assert Radians(2).max(&Radians(1)) == Radians(2);
assert max(&Radians(1), &Radians(2)) == Radians(2);
assert max(&Radians(2), &Radians(1)) == Radians(2);
assert Degrees(1).max(&Degrees(2)) == Degrees(2);
assert Degrees(2).max(&Degrees(1)) == Degrees(2);
assert max(&Degrees(1), &Degrees(2)) == Degrees(2);
assert max(&Degrees(2), &Degrees(1)) == Degrees(2);
assert max(&Vec2::new(1, 2), &Vec2::new(2, 1)) == Vec2::new(2, 2);
assert max(&Vec3::new(1, 2, 3), &Vec3::new(3, 2, 1)) == Vec3::new(3, 2, 3);
assert max(&Vec4::new(1, 2, 3, 4), &Vec4::new(4, 3, 2, 1)) == Vec4::new(4, 3, 3, 4);