Use traits from numeric library in funs module
This commit is contained in:
parent
49c27ad4f1
commit
04e7ab0dfb
5 changed files with 456 additions and 808 deletions
|
@ -5,180 +5,11 @@
|
|||
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
*/
|
||||
|
||||
use angle::{Radians, Degrees};
|
||||
use numeric::traits::*;
|
||||
|
||||
use vec::{Vec2, Vec3, Vec4};
|
||||
|
||||
pub trait Sign {
|
||||
pure fn abs(&self) -> self;
|
||||
pure fn sign(&self) -> self;
|
||||
}
|
||||
|
||||
#[inline(always)] pub pure fn abs<T:Sign>(x: &T) -> T { x.abs() }
|
||||
#[inline(always)] pub pure fn sign<T:Sign>(x: &T) -> T { x.sign() }
|
||||
|
||||
pub impl i8: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> i8 { if (*self) >= 0 { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> i8 { if (*self) > 0 { 1 } else if (*self) == 0 { 0 } else { -1 } }
|
||||
}
|
||||
|
||||
pub impl i16: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> i16 { if (*self) >= 0 { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> i16 { if (*self) > 0 { 1 } else if (*self) == 0 { 0 } else { -1 } }
|
||||
}
|
||||
|
||||
pub impl i32: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> i32 { if (*self) >= 0 { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> i32 { if (*self) > 0 { 1 } else if (*self) == 0 { 0 } else { -1 } }
|
||||
}
|
||||
|
||||
pub impl i64: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> i64 { if (*self) >= 0 { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> i64 { if (*self) > 0 { 1 } else if (*self) == 0 { 0 } else { -1 } }
|
||||
}
|
||||
|
||||
pub impl int: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> int { if (*self) >= 0 { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> int { if (*self) > 0 { 1 } else if (*self) == 0 { 0 } else { -1 } }
|
||||
}
|
||||
|
||||
pub impl f32: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> f32 { if (*self) >= 0f32 { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> f32 { if (*self) > 0f32 { 1f32 } else if (*self) == 0f32 { 0f32 } else { -1f32 } }
|
||||
}
|
||||
|
||||
pub impl f64: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> f64 { if (*self) >= 0f64 { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> f64 { if (*self) > 0f64 { 1f64 } else if (*self) == 0f64 { 0f64 } else { -1f64 } }
|
||||
}
|
||||
|
||||
pub impl float: Sign {
|
||||
#[inline(always)] pure fn abs(&self) -> float { if (*self) >= 0f { (*self) } else { -(*self) } }
|
||||
#[inline(always)] pure fn sign(&self) -> float { if (*self) > 0f { 1f } else if (*self) == 0f { 0f } else { -1f } }
|
||||
}
|
||||
|
||||
|
||||
pub impl<T:Sign> Radians<T>: Sign{
|
||||
#[inline(always)] pure fn abs(&self) -> Radians<T> { Radians(abs(&**self)) }
|
||||
#[inline(always)] pure fn sign(&self) -> Radians<T> { Radians(sign(&**self)) }
|
||||
}
|
||||
|
||||
pub impl<T:Sign> Degrees<T>: Sign{
|
||||
#[inline(always)] pure fn abs(&self) -> Degrees<T> { Degrees(abs(&**self)) }
|
||||
#[inline(always)] pure fn sign(&self) -> Degrees<T> { Degrees(sign(&**self)) }
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub impl<T:Copy Sign> Vec2<T>: Sign {
|
||||
#[inline(always)]
|
||||
pure fn abs(&self) -> Vec2<T> {
|
||||
Vec2::new(abs(&self[0]),
|
||||
abs(&self[1]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sign(&self) -> Vec2<T> {
|
||||
Vec2::new(sign(&self[0]),
|
||||
sign(&self[1]))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Sign> Vec3<T>: Sign {
|
||||
#[inline(always)]
|
||||
pure fn abs(&self) -> Vec3<T> {
|
||||
Vec3::new(abs(&self[0]),
|
||||
abs(&self[1]),
|
||||
abs(&self[2]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sign(&self) -> Vec3<T> {
|
||||
Vec3::new(sign(&self[0]),
|
||||
sign(&self[1]),
|
||||
sign(&self[2]))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Sign> Vec4<T>: Sign {
|
||||
#[inline(always)]
|
||||
pure fn abs(&self) -> Vec4<T> {
|
||||
Vec4::new(abs(&self[0]),
|
||||
abs(&self[1]),
|
||||
abs(&self[2]),
|
||||
abs(&self[3]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sign(&self) -> Vec4<T> {
|
||||
Vec4::new(sign(&self[0]),
|
||||
sign(&self[1]),
|
||||
sign(&self[2]),
|
||||
sign(&self[3]))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Approx {
|
||||
pure fn floor(&self) -> self;
|
||||
pure fn trunc(&self) -> self;
|
||||
pure fn round(&self) -> self;
|
||||
// pure fn roundEven(&self) -> self;
|
||||
pure fn ceil(&self) -> self;
|
||||
pure fn fract(&self) -> self;
|
||||
}
|
||||
|
||||
#[inline(always)] pub pure fn floor<T:Approx>(x: &T) -> T { x.floor() }
|
||||
#[inline(always)] pub pure fn trunc<T:Approx>(x: &T) -> T { x.trunc() }
|
||||
#[inline(always)] pub pure fn round<T:Approx>(x: &T) -> T { x.round() }
|
||||
// #[inline(always)] pub pure fn roundEven<T:Approx>(x: &T) -> T { x.roundEven() }
|
||||
#[inline(always)] pub pure fn ceil<T:Approx>(x: &T) -> T { x.ceil() }
|
||||
#[inline(always)] pub pure fn fract<T:Approx>(x: &T) -> T { x.fract() }
|
||||
|
||||
pub impl f32: Approx {
|
||||
#[inline(always)] pure fn floor(&self) -> f32 { f32::floor(*self) }
|
||||
#[inline(always)] pure fn trunc(&self) -> f32 { f32::trunc(*self) }
|
||||
#[inline(always)] pure fn round(&self) -> f32 { f32::round(*self) }
|
||||
// #[inline(always)] pure fn roundEven(&self) -> f32 {}
|
||||
#[inline(always)] pure fn ceil(&self) -> f32 { f32::ceil(*self) }
|
||||
#[inline(always)] pure fn fract(&self) -> f32 { (*self) - floor(self) }
|
||||
}
|
||||
|
||||
pub impl f64: Approx {
|
||||
#[inline(always)] pure fn floor(&self) -> f64 { f64::floor(*self) }
|
||||
#[inline(always)] pure fn trunc(&self) -> f64 { f64::trunc(*self) }
|
||||
#[inline(always)] pure fn round(&self) -> f64 { f64::round(*self) }
|
||||
// #[inline(always)] pure fn roundEven(&self) -> f64 {}
|
||||
#[inline(always)] pure fn ceil(&self) -> f64 { f64::ceil(*self) }
|
||||
#[inline(always)] pure fn fract(&self) -> f64 { (*self) - floor(self) }
|
||||
}
|
||||
|
||||
pub impl float: Approx {
|
||||
#[inline(always)] pure fn floor(&self) -> float { f64::floor(*self as f64) as float }
|
||||
#[inline(always)] pure fn trunc(&self) -> float { f64::trunc(*self as f64) as float }
|
||||
#[inline(always)] pure fn round(&self) -> float { f64::round(*self as f64) as float }
|
||||
// #[inline(always)] pure fn roundEven(&self) -> float {}
|
||||
#[inline(always)] pure fn ceil(&self) -> float { f64::ceil(*self as f64) as float }
|
||||
#[inline(always)] pure fn fract(&self) -> float { (*self) - floor(self) }
|
||||
}
|
||||
|
||||
|
||||
pub impl<T:Approx> Radians<T>: Approx{
|
||||
#[inline(always)] pure fn floor(&self) -> Radians<T> { Radians(floor(&**self)) }
|
||||
#[inline(always)] pure fn trunc(&self) -> Radians<T> { Radians(trunc(&**self)) }
|
||||
#[inline(always)] pure fn round(&self) -> Radians<T> { Radians(round(&**self)) }
|
||||
// #[inline(always)] pure fn roundEven(&self) -> Radians<T> { Radians(roundEven(&**self)) }
|
||||
#[inline(always)] pure fn ceil(&self) -> Radians<T> { Radians(ceil(&**self)) }
|
||||
#[inline(always)] pure fn fract(&self) -> Radians<T> { Radians(fract(&**self)) }
|
||||
}
|
||||
|
||||
pub impl<T:Approx> Degrees<T>: Approx{
|
||||
#[inline(always)] pure fn floor(&self) -> Degrees<T> { Degrees(floor(&**self)) }
|
||||
#[inline(always)] pure fn trunc(&self) -> Degrees<T> { Degrees(trunc(&**self)) }
|
||||
#[inline(always)] pure fn round(&self) -> Degrees<T> { Degrees(round(&**self)) }
|
||||
// #[inline(always)] pure fn roundEven(&self) -> Degrees<T> { Degrees(roundEven(&**self)) }
|
||||
#[inline(always)] pure fn ceil(&self) -> Degrees<T> { Degrees(ceil(&**self)) }
|
||||
#[inline(always)] pure fn fract(&self) -> Degrees<T> { Degrees(fract(&**self)) }
|
||||
}
|
||||
|
||||
// Approx
|
||||
|
||||
pub impl<T:Copy Approx> Vec2<T>: Approx {
|
||||
#[inline(always)]
|
||||
|
@ -216,7 +47,6 @@ pub impl<T:Copy Approx> Vec2<T>: Approx {
|
|||
Vec2::new(fract(&self[0]),
|
||||
fract(&self[1]))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub impl<T:Copy Approx> Vec3<T>: Approx {
|
||||
|
@ -261,7 +91,6 @@ pub impl<T:Copy Approx> Vec3<T>: Approx {
|
|||
fract(&self[1]),
|
||||
fract(&self[2]))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub impl<T:Copy Approx> Vec4<T>: Approx {
|
||||
|
@ -312,275 +141,9 @@ pub impl<T:Copy Approx> Vec4<T>: Approx {
|
|||
fract(&self[2]),
|
||||
fract(&self[3]))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub trait Extent {
|
||||
pure fn min(&self, other: &self) -> self;
|
||||
pure fn max(&self, other: &self) -> self;
|
||||
pure fn clamp(&self, mn: &self, mx: &self) -> self;
|
||||
}
|
||||
|
||||
#[inline(always)] pub pure fn min<T:Extent>(a: &T, b: &T) -> T { a.min(b) }
|
||||
#[inline(always)] pub pure fn max<T:Extent>(a: &T, b: &T) -> T { a.max(b) }
|
||||
#[inline(always)] pub pure fn clamp<T:Extent>(x: &T, mn: &T, mx: &T) -> T { x.clamp(mn, mx) }
|
||||
|
||||
pub impl u8: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &u8) -> u8 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &u8) -> u8 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &u8, mx: &u8) -> u8 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl u16: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &u16) -> u16 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &u16) -> u16 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &u16, mx: &u16) -> u16 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl u32: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &u32) -> u32 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &u32) -> u32 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &u32, mx: &u32) -> u32 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl u64: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &u64) -> u64 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &u64) -> u64 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &u64, mx: &u64) -> u64 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl uint: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &uint) -> uint {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &uint) -> uint {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &uint, mx: &uint) -> uint {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl i8: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &i8) -> i8 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &i8) -> i8 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &i8, mx: &i8) -> i8 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl i16: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &i16) -> i16 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &i16) -> i16 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &i16, mx: &i16) -> i16 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl i32: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &i32) -> i32 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &i32) -> i32 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &i32, mx: &i32) -> i32 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl i64: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &i64) -> i64 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &i64) -> i64 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &i64, mx: &i64) -> i64 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl int: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &int) -> int {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &int) -> int {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &int, mx: &int) -> int {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl f32: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &f32) -> f32 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &f32) -> f32 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl f64: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &f64) -> f64 {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &f64) -> f64 {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &f64, mx: &f64) -> f64 {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
pub impl float: Extent {
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &float) -> float {
|
||||
if (*self) < (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &float) -> float {
|
||||
if (*self) > (*other) { (*self) } else { (*other) }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &float, mx: &float) -> float {
|
||||
min(&max(self, mn), mx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub impl<T:Copy Extent> Radians<T>: Extent{
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &Radians<T>) -> Radians<T> {
|
||||
Radians(min(&**self, &**other))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &Radians<T>) -> Radians<T> {
|
||||
Radians(max(&**self, &**other))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &Radians<T>, mx: &Radians<T>) -> Radians<T> {
|
||||
Radians((**self).clamp(&**mn, &**mx))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Extent> Degrees<T>: Extent{
|
||||
#[inline(always)]
|
||||
pure fn min(&self, other: &Degrees<T>) -> Degrees<T> {
|
||||
Degrees(min(&**self, &**other))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max(&self, other: &Degrees<T>) -> Degrees<T> {
|
||||
Degrees(max(&**self, &**other))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn clamp(&self, mn: &Degrees<T>, mx: &Degrees<T>) -> Degrees<T> {
|
||||
Degrees((**self).clamp(&**mn, &**mx))
|
||||
}
|
||||
}
|
||||
|
||||
// Extent
|
||||
|
||||
pub impl<T:Copy Extent> Vec2<T>: Extent {
|
||||
#[inline(always)]
|
||||
|
@ -651,91 +214,7 @@ pub impl<T:Copy Extent> Vec4<T>: Extent {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub trait Mix {
|
||||
pure fn mix(&self, other: &self, value: &self) -> self;
|
||||
pure fn smooth_step(&self, edge0: &self, edge1: &self) -> self;
|
||||
pure fn step(&self, edge: &self) -> self;
|
||||
}
|
||||
|
||||
#[inline(always)] pub pure fn mix<T:Mix>(a: &T, b: &T, value: &T) -> T { a.mix(b, value) }
|
||||
#[inline(always)] pub pure fn smooth_step<T:Mix>(x: &T, edge0: &T, edge1: &T) -> T { x.smooth_step(edge0, edge1) }
|
||||
#[inline(always)] pub pure fn step<T:Mix>(x: &T, edge: &T) -> T { x.step(edge) }
|
||||
|
||||
pub impl f32: Mix {
|
||||
#[inline(always)]
|
||||
pure fn mix(&self, other: &f32, value: &f32) -> f32 {
|
||||
(*self) * (1.0 - (*value)) + (*other) * (*value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn smooth_step(&self, edge0: &f32, edge1: &f32) -> f32 {
|
||||
let t = clamp(&((*self - *edge0) / (*edge1 - *edge0)), &0.0, &1.0);
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn step(&self, edge: &f32) -> f32 {
|
||||
if (*self) < (*edge) { 0.0 } else { 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
pub impl f64: Mix {
|
||||
#[inline(always)]
|
||||
pure fn mix(&self, other: &f64, value: &f64) -> f64 {
|
||||
(*self) * (1.0 - (*value)) + (*other) * (*value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn smooth_step(&self, edge0: &f64, edge1: &f64) -> f64 {
|
||||
let t = clamp(&((*self - *edge0) / (*edge1 - *edge0)), &0.0, &1.0);
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn step(&self, edge: &f64) -> f64 {
|
||||
if (*self) < (*edge) { 0.0 } else { 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
pub impl float: Mix {
|
||||
#[inline(always)]
|
||||
pure fn mix(&self, other: &float, value: &float) -> float {
|
||||
(*self) * (1.0 - (*value)) + (*other) * (*value)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn smooth_step(&self, edge0: &float, edge1: &float) -> float {
|
||||
let t = clamp(&((*self - *edge0) / (*edge1 - *edge0)), &0.0, &1.0);
|
||||
return t * t * (3.0 - 2.0 * t);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn step(&self, edge: &float) -> float {
|
||||
if (*self) < (*edge) { 0.0 } else { 1.0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// FIXME: ICE!!
|
||||
|
||||
pub impl<T:Mix> Radians<T>: Mix {
|
||||
#[inline(always)]
|
||||
pure fn mix(&self, other: &Radians<T>, value: &Radians<T>) -> Radians<T> {
|
||||
Radians((**self).mix(&**other, &**value))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn smooth_step(&self, edge0: &Radians<T>, edge1: &Radians<T>) -> Radians<T> {
|
||||
Radians((**self).smooth_step(&**edge0, &**edge1))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn step(&self, edge: &Radians<T>) -> Radians<T> {
|
||||
Radians((**self).step(&**edge))
|
||||
}
|
||||
}
|
||||
|
||||
// Mix
|
||||
|
||||
pub impl<T:Copy Mix> Vec2<T>: Mix {
|
||||
#[inline(always)]
|
||||
|
@ -805,3 +284,53 @@ pub impl<T:Copy Mix> Vec4<T>: Mix {
|
|||
self[3].step(&edge[3]))
|
||||
}
|
||||
}
|
||||
|
||||
// Sign
|
||||
|
||||
pub impl<T:Copy Sign> Vec2<T>: Sign {
|
||||
#[inline(always)]
|
||||
pure fn abs(&self) -> Vec2<T> {
|
||||
Vec2::new(abs(&self[0]),
|
||||
abs(&self[1]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sign(&self) -> Vec2<T> {
|
||||
Vec2::new(sign(&self[0]),
|
||||
sign(&self[1]))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Sign> Vec3<T>: Sign {
|
||||
#[inline(always)]
|
||||
pure fn abs(&self) -> Vec3<T> {
|
||||
Vec3::new(abs(&self[0]),
|
||||
abs(&self[1]),
|
||||
abs(&self[2]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sign(&self) -> Vec3<T> {
|
||||
Vec3::new(sign(&self[0]),
|
||||
sign(&self[1]),
|
||||
sign(&self[2]))
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Sign> Vec4<T>: Sign {
|
||||
#[inline(always)]
|
||||
pure fn abs(&self) -> Vec4<T> {
|
||||
Vec4::new(abs(&self[0]),
|
||||
abs(&self[1]),
|
||||
abs(&self[2]),
|
||||
abs(&self[3]))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn sign(&self) -> Vec4<T> {
|
||||
Vec4::new(sign(&self[0]),
|
||||
sign(&self[1]),
|
||||
sign(&self[2]),
|
||||
sign(&self[3]))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,55 +5,11 @@
|
|||
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
*/
|
||||
|
||||
use numeric::traits::*;
|
||||
|
||||
use vec::{Vec2, Vec3, Vec4};
|
||||
|
||||
pub trait Exp {
|
||||
pure fn pow(&self, n: &self) -> self;
|
||||
pure fn exp(&self) -> self;
|
||||
pure fn log_(&self) -> self;
|
||||
pure fn exp2(&self) -> self;
|
||||
pure fn log2(&self) -> self;
|
||||
pure fn sqrt(&self) -> self;
|
||||
pure fn inv_sqrt(&self) -> self;
|
||||
}
|
||||
|
||||
#[inline(always)] pub pure fn pow<T:Exp>(x: &T, n: &T) -> T { x.pow(n) }
|
||||
#[inline(always)] pub pure fn exp<T:Exp>(x: &T) -> T { x.exp() }
|
||||
#[inline(always)] pub pure fn log_<T:Exp>(x: &T) -> T { x.log_() }
|
||||
#[inline(always)] pub pure fn exp2<T:Exp>(x: &T) -> T { x.exp2() }
|
||||
#[inline(always)] pub pure fn log2<T:Exp>(x: &T) -> T { x.log2() }
|
||||
#[inline(always)] pub pure fn sqrt<T:Exp>(x: &T) -> T { x.sqrt() }
|
||||
#[inline(always)] pub pure fn inv_sqrt<T:Exp>(x: &T) -> T { x.inv_sqrt() }
|
||||
|
||||
pub impl f32: Exp {
|
||||
#[inline(always)] pure fn pow(&self, n: &f32) -> f32 { f32::pow(*self, *n) }
|
||||
#[inline(always)] pure fn exp(&self) -> f32 { f32::exp(*self) }
|
||||
#[inline(always)] pure fn log_(&self) -> f32 { f32::ln(*self) }
|
||||
#[inline(always)] pure fn exp2(&self) -> f32 { f32::exp2(*self) }
|
||||
#[inline(always)] pure fn log2(&self) -> f32 { f32::log2(*self) }
|
||||
#[inline(always)] pure fn sqrt(&self) -> f32 { f32::sqrt(*self) }
|
||||
#[inline(always)] pure fn inv_sqrt(&self) -> f32 { 1f32 / self.sqrt() } // TODO: optimise? need a wizard
|
||||
}
|
||||
|
||||
pub impl f64: Exp {
|
||||
#[inline(always)] pure fn pow(&self, n: &f64) -> f64 { f64::pow(*self, *n) }
|
||||
#[inline(always)] pure fn exp(&self) -> f64 { f64::exp(*self) }
|
||||
#[inline(always)] pure fn log_(&self) -> f64 { f64::ln(*self) }
|
||||
#[inline(always)] pure fn exp2(&self) -> f64 { f64::exp2(*self) }
|
||||
#[inline(always)] pure fn log2(&self) -> f64 { f64::log2(*self) }
|
||||
#[inline(always)] pure fn sqrt(&self) -> f64 { f64::sqrt(*self) }
|
||||
#[inline(always)] pure fn inv_sqrt(&self) -> f64 { 1f64 / self.sqrt() } // TODO: optimise? need a wizard
|
||||
}
|
||||
|
||||
pub impl float: Exp {
|
||||
#[inline(always)] pure fn pow(&self, n: &float) -> float { f64::pow(*self as f64, *n as f64) as float }
|
||||
#[inline(always)] pure fn exp(&self) -> float { f64::exp(*self as f64) as float }
|
||||
#[inline(always)] pure fn log_(&self) -> float { f64::ln(*self as f64) as float }
|
||||
#[inline(always)] pure fn exp2(&self) -> float { f64::exp2(*self as f64) as float }
|
||||
#[inline(always)] pure fn log2(&self) -> float { f64::log2(*self as f64) as float }
|
||||
#[inline(always)] pure fn sqrt(&self) -> float { f64::sqrt(*self as f64) as float }
|
||||
#[inline(always)] pure fn inv_sqrt(&self) -> float { 1f / self.sqrt() } // TODO: optimise? need a wizard
|
||||
}
|
||||
// Exp
|
||||
|
||||
pub impl<T:Copy Exp> Vec2<T>: Exp {
|
||||
#[inline(always)]
|
||||
|
|
264
src/funs/relational.rs
Normal file
264
src/funs/relational.rs
Normal file
|
@ -0,0 +1,264 @@
|
|||
/**
|
||||
* Vector Relational Functions
|
||||
*
|
||||
* This module corresponds to Section 8.7 of the [GLSL 4.30.6 specification]
|
||||
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
*/
|
||||
|
||||
use core::cmp::{Eq, Ord};
|
||||
use vec::{Vector, Vec2, Vec3, Vec4};
|
||||
|
||||
/**
|
||||
* Component-wise vector comparison methods
|
||||
*/
|
||||
pub trait OrdinalVector<T, BoolVec>: Vector<T> {
|
||||
/**
|
||||
* Component-wise compare of `self < other`
|
||||
*/
|
||||
pure fn less_than(&self, other: &self) -> BoolVec;
|
||||
|
||||
/**
|
||||
* Component-wise compare of `self <= other`
|
||||
*/
|
||||
pure fn less_than_equal(&self, other: &self) -> BoolVec;
|
||||
|
||||
/**
|
||||
* Component-wise compare of `self > other`
|
||||
*/
|
||||
pure fn greater_than(&self, other: &self) -> BoolVec;
|
||||
|
||||
/**
|
||||
* Component-wise compare of `self >= other`
|
||||
*/
|
||||
pure fn greater_than_equal(&self, other: &self) -> BoolVec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Component-wise equality comparison methods
|
||||
*/
|
||||
pub trait EquableVector<T, BoolVec>: Vector<T> {
|
||||
/**
|
||||
* Component-wise compare of `self == other`
|
||||
*/
|
||||
pure fn equal(&self, other: &self) -> BoolVec;
|
||||
|
||||
/**
|
||||
* Component-wise compare of `self != other`
|
||||
*/
|
||||
pure fn not_equal(&self, other: &self) -> BoolVec;
|
||||
}
|
||||
|
||||
/**
|
||||
* A vector with boolean components
|
||||
*/
|
||||
pub trait BooleanVector: Vector<bool> {
|
||||
/**
|
||||
* # Return value
|
||||
*
|
||||
* `true` if of any component is `true`
|
||||
*/
|
||||
pure fn any(&self) -> bool;
|
||||
|
||||
/**
|
||||
* # Return value
|
||||
*
|
||||
* `true` only if all components are `true`
|
||||
*/
|
||||
pure fn all(&self) -> bool;
|
||||
|
||||
/**
|
||||
* # Return value
|
||||
*
|
||||
* the component-wise logical complement
|
||||
*/
|
||||
pure fn not(&self) -> self;
|
||||
}
|
||||
|
||||
pub impl<T:Copy Ord> Vec2<T>: OrdinalVector<T, Vec2<bool>> {
|
||||
#[inline(always)]
|
||||
pure fn less_than(&self, other: &Vec2<T>) -> Vec2<bool> {
|
||||
Vec2::new(self[0] < other[0],
|
||||
self[1] < other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn less_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
||||
Vec2::new(self[0] <= other[0],
|
||||
self[1] <= other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn greater_than(&self, other: &Vec2<T>) -> Vec2<bool> {
|
||||
Vec2::new(self[0] > other[0],
|
||||
self[1] > other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn greater_than_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
||||
Vec2::new(self[0] >= other[0],
|
||||
self[1] >= other[1])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Eq> Vec2<T>: EquableVector<T, Vec2<bool>> {
|
||||
#[inline(always)]
|
||||
pure fn equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
||||
Vec2::new(self[0] == other[0],
|
||||
self[1] == other[1])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn not_equal(&self, other: &Vec2<T>) -> Vec2<bool> {
|
||||
Vec2::new(self[0] != other[0],
|
||||
self[1] != other[1])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl Vec2<bool>: BooleanVector {
|
||||
#[inline(always)]
|
||||
pure fn any(&self) -> bool {
|
||||
self[0] || self[1]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn all(&self) -> bool {
|
||||
self[0] && self[1]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn not(&self) -> Vec2<bool> {
|
||||
Vec2::new(!self[0], !self[1])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Ord> Vec3<T>: OrdinalVector<T, Vec3<bool>> {
|
||||
#[inline(always)]
|
||||
pure fn less_than(&self, other: &Vec3<T>) -> Vec3<bool> {
|
||||
Vec3::new(self[0] < other[0],
|
||||
self[1] < other[1],
|
||||
self[2] < other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn less_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
||||
Vec3::new(self[0] <= other[0],
|
||||
self[1] <= other[1],
|
||||
self[2] <= other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn greater_than(&self, other: &Vec3<T>) -> Vec3<bool> {
|
||||
Vec3::new(self[0] > other[0],
|
||||
self[1] > other[1],
|
||||
self[2] > other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn greater_than_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
||||
Vec3::new(self[0] >= other[0],
|
||||
self[1] >= other[1],
|
||||
self[2] >= other[2])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Eq> Vec3<T>: EquableVector<T, Vec3<bool>> {
|
||||
#[inline(always)]
|
||||
pure fn equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
||||
Vec3::new(self[0] == other[0],
|
||||
self[1] == other[1],
|
||||
self[2] == other[2])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn not_equal(&self, other: &Vec3<T>) -> Vec3<bool> {
|
||||
Vec3::new(self[0] != other[0],
|
||||
self[1] != other[1],
|
||||
self[2] != other[2])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl Vec3<bool>: BooleanVector {
|
||||
#[inline(always)]
|
||||
pure fn any(&self) -> bool {
|
||||
self[0] || self[1] || self[2]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn all(&self) -> bool {
|
||||
self[0] && self[1] && self[2]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn not(&self) -> Vec3<bool> {
|
||||
Vec3::new(!self[0], !self[1], !self[2])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Ord> Vec4<T>: OrdinalVector<T, Vec4<bool>> {
|
||||
#[inline(always)]
|
||||
pure fn less_than(&self, other: &Vec4<T>) -> Vec4<bool> {
|
||||
Vec4::new(self[0] < other[0],
|
||||
self[1] < other[1],
|
||||
self[2] < other[2],
|
||||
self[3] < other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn less_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
||||
Vec4::new(self[0] <= other[0],
|
||||
self[1] <= other[1],
|
||||
self[2] <= other[2],
|
||||
self[3] <= other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn greater_than(&self, other: &Vec4<T>) -> Vec4<bool> {
|
||||
Vec4::new(self[0] > other[0],
|
||||
self[1] > other[1],
|
||||
self[2] > other[2],
|
||||
self[3] > other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn greater_than_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
||||
Vec4::new(self[0] >= other[0],
|
||||
self[1] >= other[1],
|
||||
self[2] >= other[2],
|
||||
self[3] >= other[3])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T:Copy Eq> Vec4<T>: EquableVector<T, Vec4<bool>> {
|
||||
#[inline(always)]
|
||||
pure fn equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
||||
Vec4::new(self[0] == other[0],
|
||||
self[1] == other[1],
|
||||
self[2] == other[2],
|
||||
self[3] == other[3])
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn not_equal(&self, other: &Vec4<T>) -> Vec4<bool> {
|
||||
Vec4::new(self[0] != other[0],
|
||||
self[1] != other[1],
|
||||
self[2] != other[2],
|
||||
self[3] != other[3])
|
||||
}
|
||||
}
|
||||
|
||||
pub impl Vec4<bool>: BooleanVector {
|
||||
#[inline(always)]
|
||||
pure fn any(&self) -> bool {
|
||||
self[0] || self[1] || self[2] || self[3]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn all(&self) -> bool {
|
||||
self[0] && self[1] && self[2] && self[3]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn not(&self) -> Vec4<bool> {
|
||||
Vec4::new(!self[0], !self[1], !self[2], !self[3])
|
||||
}
|
||||
}
|
|
@ -4,257 +4,156 @@
|
|||
* This module corresponds to Section 8.1 of the [GLSL 4.30.6 specification]
|
||||
* (http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf).
|
||||
*/
|
||||
use angle::{Radians, Degrees};
|
||||
use num::types::{Number, Float};
|
||||
|
||||
use numeric::traits::*;
|
||||
use numeric::types::angle::{Angle, Radians};
|
||||
use numeric::types::float::Float;
|
||||
|
||||
use vec::{Vec3, Vec2, Vec4};
|
||||
|
||||
/**
|
||||
* Triganomic functions
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Trigonometric_functions
|
||||
*/
|
||||
priv trait Trig<T> {
|
||||
pure fn sin(&self) -> T;
|
||||
pure fn cos(&self) -> T;
|
||||
pure fn tan(&self) -> T;
|
||||
}
|
||||
// // Trig
|
||||
|
||||
#[inline(always)] pub pure fn sin<T:Trig<R>, R>(theta: &T) -> R { theta.sin() }
|
||||
#[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() }
|
||||
|
||||
priv impl<T:Copy Float> Radians<T>: Trig<T> {
|
||||
#[inline(always)] pure fn sin(&self) -> T { Number::from(f64::sin(Number::from(**self))) }
|
||||
#[inline(always)] pure fn cos(&self) -> T { Number::from(f64::cos(Number::from(**self))) }
|
||||
#[inline(always)] pure fn tan(&self) -> T { Number::from(f64::tan(Number::from(**self))) }
|
||||
}
|
||||
|
||||
pub impl<T:Copy Float> Degrees<T>: Trig<T> {
|
||||
#[inline(always)] pure fn sin(&self) -> T { Number::from(f64::sin(Number::from(*self.to_radians()))) }
|
||||
#[inline(always)] pure fn cos(&self) -> T { Number::from(f64::cos(Number::from(*self.to_radians()))) }
|
||||
#[inline(always)] pure fn tan(&self) -> T { Number::from(f64::tan(Number::from(*self.to_radians()))) }
|
||||
}
|
||||
|
||||
pub impl<T:Copy Float> Vec2<Radians<T>>: Trig<Vec2<T>> {
|
||||
#[inline(always)]
|
||||
pure fn sin(&self) -> Vec2<T> {
|
||||
Vec2::new(sin(&self[0]),
|
||||
sin(&self[1]))
|
||||
}
|
||||
// pub impl<T:Copy Float, A:Copy Angle<T>> Vec2<A>: Trig<Vec2<T>> {
|
||||
// #[inline(always)]
|
||||
// pure fn sin(&self) -> Vec2<T> {
|
||||
// Vec2::new(sin(&self[0]),
|
||||
// sin(&self[1]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn cos(&self) -> Vec2<T> {
|
||||
Vec2::new(cos(&self[0]),
|
||||
cos(&self[1]))
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn cos(&self) -> Vec2<T> {
|
||||
// Vec2::new(cos(&self[0]),
|
||||
// cos(&self[1]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn tan(&self) -> Vec2<T> {
|
||||
Vec2::new(tan(&self[0]),
|
||||
tan(&self[1]))
|
||||
}
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn tan(&self) -> Vec2<T> {
|
||||
// Vec2::new(tan(&self[0]),
|
||||
// tan(&self[1]))
|
||||
// }
|
||||
// }
|
||||
|
||||
pub impl<T:Copy Float> Vec3<Radians<T>>: Trig<Vec3<T>> {
|
||||
#[inline(always)]
|
||||
pure fn sin(&self) -> Vec3<T> {
|
||||
Vec3::new(sin(&self[0]),
|
||||
sin(&self[1]),
|
||||
sin(&self[2]))
|
||||
}
|
||||
// pub impl<T:Copy Float, A:Copy Angle<T>> Vec3<A>: Trig<Vec3<T>> {
|
||||
// #[inline(always)]
|
||||
// pure fn sin(&self) -> Vec3<T> {
|
||||
// Vec3::new(sin(&self[0]),
|
||||
// sin(&self[1]),
|
||||
// sin(&self[2]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn cos(&self) -> Vec3<T> {
|
||||
Vec3::new(cos(&self[0]),
|
||||
cos(&self[1]),
|
||||
cos(&self[2]))
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn cos(&self) -> Vec3<T> {
|
||||
// Vec3::new(cos(&self[0]),
|
||||
// cos(&self[1]),
|
||||
// cos(&self[2]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn tan(&self) -> Vec3<T> {
|
||||
Vec3::new(tan(&self[0]),
|
||||
tan(&self[1]),
|
||||
tan(&self[2]))
|
||||
}
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn tan(&self) -> Vec3<T> {
|
||||
// Vec3::new(tan(&self[0]),
|
||||
// tan(&self[1]),
|
||||
// tan(&self[2]))
|
||||
// }
|
||||
// }
|
||||
|
||||
pub impl<T:Copy Float> Vec4<Radians<T>>: Trig<Vec4<T>> {
|
||||
#[inline(always)]
|
||||
pure fn sin(&self) -> Vec4<T> {
|
||||
Vec4::new(sin(&self[0]),
|
||||
sin(&self[1]),
|
||||
sin(&self[2]),
|
||||
sin(&self[3]))
|
||||
}
|
||||
// pub impl<T:Copy Float, A:Copy Angle<T>> Vec4<A>: Trig<Vec4<T>> {
|
||||
// #[inline(always)]
|
||||
// pure fn sin(&self) -> Vec4<T> {
|
||||
// Vec4::new(sin(&self[0]),
|
||||
// sin(&self[1]),
|
||||
// sin(&self[2]),
|
||||
// sin(&self[3]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn cos(&self) -> Vec4<T> {
|
||||
Vec4::new(cos(&self[0]),
|
||||
cos(&self[1]),
|
||||
cos(&self[2]),
|
||||
cos(&self[3]))
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn cos(&self) -> Vec4<T> {
|
||||
// Vec4::new(cos(&self[0]),
|
||||
// cos(&self[1]),
|
||||
// cos(&self[2]),
|
||||
// cos(&self[3]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn tan(&self) -> Vec4<T> {
|
||||
Vec4::new(tan(&self[0]),
|
||||
tan(&self[1]),
|
||||
tan(&self[2]),
|
||||
tan(&self[3]))
|
||||
}
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn tan(&self) -> Vec4<T> {
|
||||
// Vec4::new(tan(&self[0]),
|
||||
// tan(&self[1]),
|
||||
// tan(&self[2]),
|
||||
// tan(&self[3]))
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Inverse triganomic functions
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Inverse_trigonometric_functions
|
||||
*/
|
||||
pub trait InvTrig {
|
||||
pure fn asin(&self) -> Radians<self>;
|
||||
pure fn acos(&self) -> Radians<self>;
|
||||
pure fn atan(&self) -> Radians<self>;
|
||||
pure fn atan2(&self, other: &self) -> Radians<self>;
|
||||
}
|
||||
// // InvTrig
|
||||
|
||||
#[inline(always)] pub pure fn asin<T:InvTrig>(x: &T) -> Radians<T> { x.asin() }
|
||||
#[inline(always)] pub pure fn acos<T:InvTrig>(x: &T) -> Radians<T> { x.acos() }
|
||||
#[inline(always)] pub pure fn atan<T:InvTrig>(x: &T) -> Radians<T> { x.atan() }
|
||||
#[inline(always)] pub pure fn atan2<T:InvTrig>(a: &T, b: &T) -> Radians<T> { a.atan2(b) }
|
||||
|
||||
pub impl f32: InvTrig {
|
||||
#[inline(always)] pure fn asin(&self) -> Radians<f32> { Radians(f32::asin(*self)) }
|
||||
#[inline(always)] pure fn acos(&self) -> Radians<f32> { Radians(f32::acos(*self)) }
|
||||
#[inline(always)] pure fn atan(&self) -> Radians<f32> { Radians(f32::atan(*self)) }
|
||||
#[inline(always)] pure fn atan2(&self, other: &f32) -> Radians<f32> { Radians(f32::atan2(*self, *other)) }
|
||||
}
|
||||
|
||||
pub impl f64: InvTrig {
|
||||
#[inline(always)] pure fn asin(&self) -> Radians<f64> { Radians(f64::asin(*self)) }
|
||||
#[inline(always)] pure fn acos(&self) -> Radians<f64> { Radians(f64::acos(*self)) }
|
||||
#[inline(always)] pure fn atan(&self) -> Radians<f64> { Radians(f64::atan(*self)) }
|
||||
#[inline(always)] pure fn atan2(&self, other: &f64) -> Radians<f64> { Radians(f64::atan2(*self, *other)) }
|
||||
}
|
||||
|
||||
pub impl float: InvTrig {
|
||||
#[inline(always)] pure fn asin(&self) -> Radians<float> { Radians(f64::asin(*self as f64) as float) }
|
||||
#[inline(always)] pure fn acos(&self) -> Radians<float> { Radians(f64::acos(*self as f64) as float) }
|
||||
#[inline(always)] pure fn atan(&self) -> Radians<float> { Radians(f64::atan(*self as f64) as float) }
|
||||
#[inline(always)] pure fn atan2(&self, other: &float) -> Radians<float> { Radians(f64::atan2(*self as f64, *other as f64) as float) }
|
||||
}
|
||||
|
||||
// TODO: figure out how to merge with InvTrig
|
||||
pub trait InvTrigV<T> {
|
||||
pure fn asin(&self) -> T;
|
||||
pure fn acos(&self) -> T;
|
||||
pure fn atan(&self) -> T;
|
||||
}
|
||||
|
||||
pub impl<T:Copy Number InvTrig> Vec2<T>: InvTrigV<Vec2<Radians<T>>> {
|
||||
#[inline(always)]
|
||||
pure fn asin(&self) -> Vec2<Radians<T>> {
|
||||
Vec2::new(asin(&self[0]),
|
||||
asin(&self[1]))
|
||||
}
|
||||
// pub impl<T:Copy Float InvTrig> Vec2<T>: InvTrig<Vec2<Radians<T>>> {
|
||||
// #[inline(always)]
|
||||
// pure fn asin(&self) -> Vec2<Radians<T>> {
|
||||
// Vec2::new(asin(&self[0]),
|
||||
// asin(&self[1]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn acos(&self) -> Vec2<Radians<T>> {
|
||||
Vec2::new(acos(&self[0]),
|
||||
acos(&self[1]))
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn acos(&self) -> Vec2<Radians<T>> {
|
||||
// Vec2::new(acos(&self[0]),
|
||||
// acos(&self[1]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn atan(&self) -> Vec2<Radians<T>> {
|
||||
Vec2::new(atan(&self[0]),
|
||||
atan(&self[1]))
|
||||
}
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn atan(&self) -> Vec2<Radians<T>> {
|
||||
// Vec2::new(atan(&self[0]),
|
||||
// atan(&self[1]))
|
||||
// }
|
||||
// }
|
||||
|
||||
pub impl<T:Copy Number InvTrig> Vec3<T>: InvTrigV<Vec3<Radians<T>>> {
|
||||
#[inline(always)]
|
||||
pure fn asin(&self) -> Vec3<Radians<T>> {
|
||||
Vec3::new(asin(&self[0]),
|
||||
asin(&self[1]),
|
||||
asin(&self[2]))
|
||||
}
|
||||
// pub impl<T:Copy Float InvTrig> Vec3<T>: InvTrig<Vec3<Radians<T>>> {
|
||||
// #[inline(always)]
|
||||
// pure fn asin(&self) -> Vec3<Radians<T>> {
|
||||
// Vec3::new(asin(&self[0]),
|
||||
// asin(&self[1]),
|
||||
// asin(&self[2]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn acos(&self) -> Vec3<Radians<T>> {
|
||||
Vec3::new(acos(&self[0]),
|
||||
acos(&self[1]),
|
||||
acos(&self[2]))
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn acos(&self) -> Vec3<Radians<T>> {
|
||||
// Vec3::new(acos(&self[0]),
|
||||
// acos(&self[1]),
|
||||
// acos(&self[2]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn atan(&self) -> Vec3<Radians<T>> {
|
||||
Vec3::new(atan(&self[0]),
|
||||
atan(&self[1]),
|
||||
atan(&self[2]))
|
||||
}
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn atan(&self) -> Vec3<Radians<T>> {
|
||||
// Vec3::new(atan(&self[0]),
|
||||
// atan(&self[1]),
|
||||
// atan(&self[2]))
|
||||
// }
|
||||
// }
|
||||
|
||||
pub impl<T:Copy Number InvTrig> Vec4<T>: InvTrigV<Vec4<Radians<T>>> {
|
||||
#[inline(always)]
|
||||
pure fn asin(&self) -> Vec4<Radians<T>> {
|
||||
Vec4::new(asin(&self[0]),
|
||||
asin(&self[1]),
|
||||
asin(&self[2]),
|
||||
asin(&self[3]))
|
||||
}
|
||||
// pub impl<T:Copy Float InvTrig> Vec4<T>: InvTrig<Vec4<Radians<T>>> {
|
||||
// #[inline(always)]
|
||||
// pure fn asin(&self) -> Vec4<Radians<T>> {
|
||||
// Vec4::new(asin(&self[0]),
|
||||
// asin(&self[1]),
|
||||
// asin(&self[2]),
|
||||
// asin(&self[3]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn acos(&self) -> Vec4<Radians<T>> {
|
||||
Vec4::new(acos(&self[0]),
|
||||
acos(&self[1]),
|
||||
acos(&self[2]),
|
||||
acos(&self[3]))
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn acos(&self) -> Vec4<Radians<T>> {
|
||||
// Vec4::new(acos(&self[0]),
|
||||
// acos(&self[1]),
|
||||
// acos(&self[2]),
|
||||
// acos(&self[3]))
|
||||
// }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn atan(&self) -> Vec4<Radians<T>> {
|
||||
Vec4::new(atan(&self[0]),
|
||||
atan(&self[1]),
|
||||
atan(&self[2]),
|
||||
atan(&self[3]))
|
||||
}
|
||||
}
|
||||
// #[inline(always)]
|
||||
// pure fn atan(&self) -> Vec4<Radians<T>> {
|
||||
// Vec4::new(atan(&self[0]),
|
||||
// atan(&self[1]),
|
||||
// atan(&self[2]),
|
||||
// atan(&self[3]))
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Hyperbolic functions
|
||||
*
|
||||
* http://en.wikipedia.org/wiki/Hyperbolic_function
|
||||
*/
|
||||
pub trait Hyp {
|
||||
pure fn sinh(&self) -> self;
|
||||
pure fn cosh(&self) -> self;
|
||||
pure fn tanh(&self) -> self;
|
||||
// pure fn asinh() -> self;
|
||||
// pure fn acosh() -> self;
|
||||
// pure fn atanh() -> self;
|
||||
}
|
||||
|
||||
#[inline(always)] pub pure fn sinh<T:Hyp>(x: &T) -> T { x.sinh() }
|
||||
#[inline(always)] pub pure fn cosh<T:Hyp>(x: &T) -> T { x.cosh() }
|
||||
#[inline(always)] pub pure fn tanh<T:Hyp>(x: &T) -> T { x.tanh() }
|
||||
|
||||
pub impl f32: Hyp {
|
||||
#[inline(always)] pure fn sinh(&self) -> f32 { f32::sinh(*self) }
|
||||
#[inline(always)] pure fn cosh(&self) -> f32 { f32::cosh(*self) }
|
||||
#[inline(always)] pure fn tanh(&self) -> f32 { f32::tanh(*self) }
|
||||
}
|
||||
|
||||
pub impl f64: Hyp {
|
||||
#[inline(always)] pure fn sinh(&self) -> f64 { f64::sinh(*self) }
|
||||
#[inline(always)] pure fn cosh(&self) -> f64 { f64::cosh(*self) }
|
||||
#[inline(always)] pure fn tanh(&self) -> f64 { f64::tanh(*self) }
|
||||
}
|
||||
|
||||
pub impl float: Hyp {
|
||||
#[inline(always)] pure fn sinh(&self) -> float { f64::sinh(*self as f64) as float }
|
||||
#[inline(always)] pure fn cosh(&self) -> float { f64::cosh(*self as f64) as float }
|
||||
#[inline(always)] pure fn tanh(&self) -> float { f64::tanh(*self as f64) as float }
|
||||
}
|
||||
// Hyp
|
||||
|
||||
pub impl <T:Copy Hyp> Vec2<T>: Hyp {
|
||||
#[inline(always)]
|
||||
|
|
12
src/lmath.rc
12
src/lmath.rc
|
@ -29,14 +29,14 @@ mod test {
|
|||
}
|
||||
|
||||
pub mod funs {
|
||||
// #[path = "funs/common.rs"]
|
||||
// pub mod common;
|
||||
// #[path = "funs/exponential.rs"]
|
||||
// pub mod exponential;
|
||||
#[path = "funs/common.rs"]
|
||||
pub mod common;
|
||||
#[path = "funs/exponential.rs"]
|
||||
pub mod exponential;
|
||||
#[path = "funs/projection.rs"]
|
||||
pub mod projection;
|
||||
// #[path = "funs/triganomic.rs"]
|
||||
// pub mod triganomic;
|
||||
#[path = "funs/triganomic.rs"]
|
||||
pub mod triganomic;
|
||||
|
||||
#[test]
|
||||
mod test {
|
||||
|
|
Loading…
Reference in a new issue