Create relational module

This commit is contained in:
Brendan Zabarauskas 2012-11-05 20:31:52 +10:00
parent c3344b5a6f
commit 1f61701d00
5 changed files with 296 additions and 103 deletions

211
src/functions/relational.rs Normal file
View file

@ -0,0 +1,211 @@
use cmp::{Eq, Ord};
use vector::{Vec2, Vec3, Vec4};
pub trait RelationalVector<BVec> {
pure fn less_than(other: &self) -> BVec;
pure fn less_than_equal(other: &self) -> BVec;
pure fn greater_than(other: &self) -> BVec;
pure fn greater_than_equal(other: &self) -> BVec;
pure fn equal(other: &self) -> BVec;
pure fn not_equal(other: &self) -> BVec;
}
#[inline(always)] pub pure fn less_than <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.less_than(y) }
#[inline(always)] pub pure fn less_than_equal <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.less_than_equal(y) }
#[inline(always)] pub pure fn greater_than <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.greater_than(y) }
#[inline(always)] pub pure fn greater_than_equal<T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.greater_than_equal(y) }
#[inline(always)] pub pure fn equal <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.equal(y) }
#[inline(always)] pub pure fn not_equal <T:RelationalVector<BVec>, BVec>(x: &T, y: &T) -> BVec { x.not_equal(y) }
pub trait BooleanVector {
pub fn any() -> bool;
pub fn all() -> bool;
pub fn not() -> self;
}
#[inline(always)] pub fn any<T:BooleanVector>(x: &T) -> bool { x.any() }
#[inline(always)] pub fn all<T:BooleanVector>(x: &T) -> bool { x.all() }
#[inline(always)] pub fn not<T:BooleanVector>(x: &T) -> T { x.not() }
pub impl<T:Copy Ord Eq> Vec2<T>: RelationalVector<Vec2<bool>> {
#[inline(always)]
pure fn less_than(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] < other[0],
self[1] < other[1])
}
#[inline(always)]
pure fn less_than_equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] <= other[0],
self[1] <= other[1])
}
#[inline(always)]
pure fn greater_than(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] > other[0],
self[1] > other[1])
}
#[inline(always)]
pure fn greater_than_equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] >= other[0],
self[1] >= other[1])
}
#[inline(always)]
pure fn equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] == other[0],
self[1] == other[1])
}
#[inline(always)]
pure fn not_equal(other: &Vec2<T>) -> Vec2<bool> {
Vec2::new(self[0] != other[0],
self[1] != other[1])
}
}
pub impl Vec2<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1]
}
pub fn all() -> bool {
self[0] && self[1]
}
pub fn not() -> Vec2<bool> {
Vec2::new(!self[0], !self[1])
}
}
pub impl<T:Copy Ord Eq> Vec3<T>: RelationalVector<Vec3<bool>> {
#[inline(always)]
pure fn less_than(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(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(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(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] >= other[0],
self[1] >= other[1],
self[2] >= other[2])
}
#[inline(always)]
pure fn equal(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(other: &Vec3<T>) -> Vec3<bool> {
Vec3::new(self[0] != other[0],
self[1] != other[1],
self[2] != other[2])
}
}
pub impl Vec3<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1] || self[2]
}
pub fn all() -> bool {
self[0] && self[1] && self[2]
}
pub fn not() -> Vec3<bool> {
Vec3::new(!self[0], !self[1], !self[2])
}
}
pub impl<T:Copy Ord Eq> Vec4<T>: RelationalVector<Vec4<bool>> {
#[inline(always)]
pure fn less_than(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(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(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(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 equal(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(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 {
pub fn any() -> bool {
self[0] || self[1] || self[2] || self[3]
}
pub fn all() -> bool {
self[0] && self[1] && self[2] && self[3]
}
pub fn not() -> Vec4<bool> {
Vec4::new(!self[0], !self[1], !self[2], !self[3])
}
}

View file

@ -0,0 +1,70 @@
use vector::*;
use relational::*;
#[test]
fn test_BooleanVec2_trait() {
let tf = Vec2::new(true, false);
let ff = Vec2::new(false, false);
let tt = Vec2::new(true, true);
assert tf.any() == true;
assert tf.all() == false;
assert tf.not().exact_eq(&Vec2::new(false, true));
assert ff.any() == false;
assert ff.all() == false;
assert ff.not().exact_eq(&Vec2::new(true, true));
assert tt.any() == true;
assert tt.all() == true;
assert tt.not().exact_eq(&Vec2::new(false, false));
}
#[test]
fn test_BooleanVec3_trait() {
let tft = Vec3::new(true, false, true);
let fff = Vec3::new(false, false, false);
let ttt = Vec3::new(true, true, true);
assert tft.any() == true;
assert tft.all() == false;
assert tft.not().exact_eq(&Vec3::new(false, true, false));
assert fff.any() == false;
assert fff.all() == false;
assert fff.not().exact_eq(&Vec3::new(true, true, true));
assert ttt.any() == true;
assert ttt.all() == true;
assert ttt.not().exact_eq(&Vec3::new(false, false, false));
}
#[test]
fn test_BooleanVec4_trait() {
let tftf = Vec4::new(true, false, true, false);
let ffff = Vec4::new(false, false, false, false);
let tttt = Vec4::new(true, true, true, true);
assert tftf.any() == true;
assert tftf.all() == false;
assert tftf.not().exact_eq(&Vec4::new(false, true, false, true));
assert ffff.any() == false;
assert ffff.all() == false;
assert ffff.not().exact_eq(&Vec4::new(true, true, true, true));
assert tttt.any() == true;
assert tttt.all() == true;
assert tttt.not().exact_eq(&Vec4::new(false, false, false, false));
}
#[test]
fn test_BooleanVec_fns() {
let tf = Vec2::new(true, false);
let ftf = Vec3::new(false, true, false);
let tftf = Vec4::new(true, false, true, false);
assert any(&tf) == true;
assert all(&ftf) == false;
assert not(&tftf).exact_eq(&Vec4::new(false, true, false, true));
}

View file

@ -15,6 +15,14 @@ pub mod projection;
pub mod quaternion;
pub mod vector;
#[test]
mod test {
mod test_matrix;
mod test_projection;
mod test_quaternion;
mod test_vector;
}
use common::*;
pub mod common {
pub mod math;
@ -22,11 +30,11 @@ pub mod common {
pub mod ntrait;
}
pub mod functions {
pub mod relational;
#[test]
pub mod test {
pub mod test_matrix;
pub mod test_math;
pub mod test_projection;
pub mod test_quaternion;
pub mod test_vector;
mod test {
mod test_relational;
}
}

View file

@ -51,22 +51,6 @@ fn test_Vec2() {
assert c.abs() == Vec2::new( 2.0f, 1.0f);
assert c.min(&d) == Vec2::new(-2.0f, -1.0f);
assert c.max(&d) == Vec2::new( 1.0f, 0.0f);
let tf = Vec2::new(true, false);
let ff = Vec2::new(false, false);
let tt = Vec2::new(true, true);
assert tf.any() == true;
assert tf.all() == false;
assert tf.not().exact_eq(&Vec2::new(false, true));
assert ff.any() == false;
assert ff.all() == false;
assert ff.not().exact_eq(&Vec2::new(true, true));
assert tt.any() == true;
assert tt.all() == true;
assert tt.not().exact_eq(&Vec2::new(false, false));
}
#[test]
@ -122,22 +106,6 @@ fn test_Vec3() {
assert c.abs() == Vec3::new( 2.0f, 1.0f, 1.0f);
assert c.min(&d) == Vec3::new(-2.0f, -1.0f, 0.5f);
assert c.max(&d) == Vec3::new( 1.0f, 0.0f, 1.0f);
let tft = Vec3::new(true, false, true);
let fff = Vec3::new(false, false, false);
let ttt = Vec3::new(true, true, true);
assert tft.any() == true;
assert tft.all() == false;
assert tft.not().exact_eq(&Vec3::new(false, true, false));
assert fff.any() == false;
assert fff.all() == false;
assert fff.not().exact_eq(&Vec3::new(true, true, true));
assert ttt.any() == true;
assert ttt.all() == true;
assert ttt.not().exact_eq(&Vec3::new(false, false, false));
}
#[test]
@ -196,20 +164,4 @@ fn test_Vec4() {
assert c.abs() == Vec4::new( 2.0f, 1.0f, 1.0f, 2.0f);
assert c.min(&d) == Vec4::new(-2.0f, -1.0f, 0.5f, 1.0f);
assert c.max(&d) == Vec4::new( 1.0f, 0.0f, 1.0f, 2.0f);
let tftf = Vec4::new(true, false, true, false);
let ffff = Vec4::new(false, false, false, false);
let tttt = Vec4::new(true, true, true, true);
assert tftf.any() == true;
assert tftf.all() == false;
assert tftf.not().exact_eq(&Vec4::new(false, true, false, true));
assert ffff.any() == false;
assert ffff.all() == false;
assert ffff.not().exact_eq(&Vec4::new(true, true, true, true));
assert tttt.any() == true;
assert tttt.all() == true;
assert tttt.not().exact_eq(&Vec4::new(false, false, false, false));
}

View file

@ -54,12 +54,6 @@ pub trait GeometricVector<T> {
pure fn lerp(other: &self, value: T) -> self;
}
pub trait BooleanVector {
pub fn any() -> bool;
pub fn all() -> bool;
pub fn not() -> self;
}
pub trait Vector2<T> {
// pub static pure fn new(x: T, y: T) -> self;
// pub static pure fn from_value(value: T) -> self;
@ -198,20 +192,6 @@ pub impl<T:Copy Num Sqrt> Vec2<T>: GeometricVector<T> {
}
}
pub impl Vec2<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1]
}
pub fn all() -> bool {
self[0] && self[1]
}
pub fn not() -> Vec2<bool> {
Vec2::new(!self[0], !self[1])
}
}
pub impl<T:Copy> Vec2<T>: Index<uint, T> {
#[inline(always)]
pure fn index(i: uint) -> T {
@ -434,20 +414,6 @@ pub impl<T:Copy Num Sqrt> Vec3<T>: GeometricVector<T> {
}
}
pub impl Vec3<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1] || self[2]
}
pub fn all() -> bool {
self[0] && self[1] && self[2]
}
pub fn not() -> Vec3<bool> {
Vec3::new(!self[0], !self[1], !self[2])
}
}
pub impl<T:Copy> Vec3<T>: Index<uint, T> {
#[inline(always)]
pure fn index(i: uint) -> T {
@ -681,20 +647,6 @@ pub impl<T:Copy Num Sqrt> Vec4<T>: GeometricVector<T> {
}
}
pub impl Vec4<bool>: BooleanVector {
pub fn any() -> bool {
self[0] || self[1] || self[2] || self[3]
}
pub fn all() -> bool {
self[0] && self[1] && self[2] && self[3]
}
pub fn not() -> Vec4<bool> {
Vec4::new(!self[0], !self[1], !self[2], !self[3])
}
}
pub impl<T:Copy> Vec4<T>: Index<uint, T> {
#[inline(always)]
pure fn index(i: uint) -> T {