Add min and max functions to vector
This commit is contained in:
parent
015f0d8eb1
commit
820ea22407
6 changed files with 181 additions and 103 deletions
49
src/math.rs
Normal file
49
src/math.rs
Normal file
|
@ -0,0 +1,49 @@
|
|||
import cmp::Ord;
|
||||
|
||||
trait Abs {
|
||||
pure fn abs() -> self;
|
||||
}
|
||||
|
||||
impl int: Abs {
|
||||
#[inline(always)]
|
||||
pure fn abs() -> int {
|
||||
if self >= 0 { self }
|
||||
else {-self }
|
||||
}
|
||||
}
|
||||
|
||||
impl float: Abs {
|
||||
#[inline(always)]
|
||||
pure fn abs() -> float {
|
||||
if self >= 0f { self }
|
||||
else {-self }
|
||||
}
|
||||
}
|
||||
|
||||
impl f32: Abs {
|
||||
#[inline(always)]
|
||||
pure fn abs() -> f32 {
|
||||
if self >= 0f32 { self }
|
||||
else {-self }
|
||||
}
|
||||
}
|
||||
|
||||
impl f64: Abs {
|
||||
#[inline(always)]
|
||||
pure fn abs() -> f64 {
|
||||
if self >= 0f64 { self }
|
||||
else {-self }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn min<T:copy Ord>(&&a:T, &&b:T) -> T {
|
||||
if a < b { a }
|
||||
else { b }
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn max<T:copy Ord>(&&a:T, &&b:T) -> T {
|
||||
if a > b { a }
|
||||
else { b }
|
||||
}
|
|
@ -8,6 +8,7 @@
|
|||
use std;
|
||||
|
||||
mod mat;
|
||||
mod math;
|
||||
mod projection;
|
||||
mod quat;
|
||||
mod vec;
|
178
src/vec.rs
178
src/vec.rs
|
@ -1,16 +1,15 @@
|
|||
import std::cmp::FuzzyEq;
|
||||
import cmp::Ord;
|
||||
import num::Num;
|
||||
import float::{sqrt, abs, fmin, fmax};
|
||||
import float::sqrt;
|
||||
import math::{Abs, min, max};
|
||||
import to_str::ToStr;
|
||||
|
||||
// TODO: Unittests! I've probably made lots of mistakes...
|
||||
|
||||
//
|
||||
// N-dimensional Vector
|
||||
//
|
||||
trait Vector<T:Num Ord FuzzyEq> {
|
||||
pure fn dim() -> uint;
|
||||
static pure fn dim() -> uint;
|
||||
|
||||
pure fn index(&&index:uint) -> T;
|
||||
|
||||
|
@ -36,8 +35,11 @@ trait Vector<T:Num Ord FuzzyEq> {
|
|||
|
||||
pure fn lerp(&&other:self, &&value:T) -> self;
|
||||
pure fn abs() -> self;
|
||||
// pure fn min(&&other:self) -> self;
|
||||
// pure fn max(&&other:self) -> self;
|
||||
pure fn min(&&other:self) -> self;
|
||||
pure fn max(&&other:self) -> self;
|
||||
|
||||
static pure fn zero() -> self;
|
||||
static pure fn identity() -> self;
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,10 +47,15 @@ trait Vector<T:Num Ord FuzzyEq> {
|
|||
|
||||
|
||||
|
||||
|
||||
trait Vector2<T:Num Ord FuzzyEq> {
|
||||
// This is where I wish rust had properties ;)
|
||||
pure fn x() -> T;
|
||||
pure fn y() -> T;
|
||||
|
||||
// static pure fn make(x:float, y:float) -> self;
|
||||
// static pure fn unit_x() -> self;
|
||||
// static pure fn unit_y() -> self;
|
||||
}
|
||||
|
||||
trait Vector3<T:Num Ord FuzzyEq> {
|
||||
|
@ -56,6 +63,12 @@ trait Vector3<T:Num Ord FuzzyEq> {
|
|||
pure fn y() -> T;
|
||||
pure fn z() -> T;
|
||||
|
||||
// static pure fn make(x:float, y:float, z:float) -> self;
|
||||
|
||||
// static pure fn unit_x() -> self;
|
||||
// static pure fn unit_y() -> self;
|
||||
// static pure fn unit_z() -> self;
|
||||
|
||||
fn cross(&&other:self) -> self;
|
||||
}
|
||||
|
||||
|
@ -64,6 +77,13 @@ trait Vector4<T:Num Ord FuzzyEq> {
|
|||
pure fn y() -> T;
|
||||
pure fn z() -> T;
|
||||
pure fn w() -> T;
|
||||
|
||||
// static pure fn make(x:float, y:float, z:float, w:float) -> self;
|
||||
|
||||
// static pure fn unit_x() -> self;
|
||||
// static pure fn unit_y() -> self;
|
||||
// static pure fn unit_z() -> self;
|
||||
// static pure fn unit_w() -> self;
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,6 +96,11 @@ trait Vector4<T:Num Ord FuzzyEq> {
|
|||
//
|
||||
struct vec2 { data:[float * 2] }
|
||||
|
||||
const vec2_zero :vec2 = vec2 { data: [ 0f, 0f ] };
|
||||
const vec2_unit_x :vec2 = vec2 { data: [ 1f, 0f ] };
|
||||
const vec2_unit_y :vec2 = vec2 { data: [ 0f, 1f ] };
|
||||
const vec2_identity :vec2 = vec2 { data: [ 1f, 1f ] };
|
||||
|
||||
//
|
||||
// Constructor
|
||||
//
|
||||
|
@ -84,14 +109,6 @@ pure fn vec2(x:float, y:float) -> vec2 {
|
|||
vec2 { data: [ x, y ] }
|
||||
}
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#[inline(always)] pure fn vec2_zero() -> vec2 { vec2 (0f, 0f) }
|
||||
#[inline(always)] pure fn vec2_unit_x() -> vec2 { vec2 (1f, 0f) }
|
||||
#[inline(always)] pure fn vec2_unit_y() -> vec2 { vec2 (0f, 1f) }
|
||||
#[inline(always)] pure fn vec2_identity() -> vec2 { vec2 (1f, 1f) }
|
||||
|
||||
impl vec2: Vector2<float> {
|
||||
#[inline(always)] pure fn x() -> float { self.data[0] }
|
||||
#[inline(always)] pure fn y() -> float { self.data[1] }
|
||||
|
@ -99,7 +116,7 @@ impl vec2: Vector2<float> {
|
|||
|
||||
impl vec2: Vector<float> {
|
||||
#[inline(always)]
|
||||
pure fn dim() -> uint { 2 }
|
||||
static pure fn dim() -> uint { 2 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> float {
|
||||
|
@ -194,21 +211,24 @@ impl vec2: Vector<float> {
|
|||
|
||||
#[inline(always)]
|
||||
pure fn abs() -> vec2 {
|
||||
vec2(abs(self[0]),
|
||||
abs(self[1]))
|
||||
vec2(self[0].abs(),
|
||||
self[1].abs())
|
||||
}
|
||||
|
||||
// #[inline(always)]
|
||||
// pure fn min(&&other:vec2) -> vec2 {
|
||||
// vec2(fmin(self[0], other[0]),
|
||||
// fmin(self[1], other[1]))
|
||||
// }
|
||||
#[inline(always)]
|
||||
pure fn min(&&other:vec2) -> vec2 {
|
||||
vec2(min(self[0], other[0]),
|
||||
min(self[1], other[1]))
|
||||
}
|
||||
|
||||
// #[inline(always)]
|
||||
// pure fn max(&&other:vec2) -> vec2 {
|
||||
// vec2(fmin(self[0], other[0]),
|
||||
// fmin(self[1], other[1]))
|
||||
// }
|
||||
#[inline(always)]
|
||||
pure fn max(&&other:vec2) -> vec2 {
|
||||
vec2(max(self[0], other[0]),
|
||||
max(self[1], other[1]))
|
||||
}
|
||||
|
||||
#[inline(always)] static pure fn zero() -> vec2 { vec2(1f, 1f) }
|
||||
#[inline(always)] static pure fn identity() -> vec2 { vec2(1f, 1f) }
|
||||
}
|
||||
|
||||
impl vec2: ToStr {
|
||||
|
@ -227,14 +247,11 @@ impl vec2: ToStr {
|
|||
//
|
||||
struct vec3 { data:[float * 3] }
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#[inline(always)] pure fn vec3_zero() -> vec3 { vec3(0f, 0f, 0f) }
|
||||
#[inline(always)] pure fn vec3_unit_x() -> vec3 { vec3(1f, 0f, 0f) }
|
||||
#[inline(always)] pure fn vec3_unit_y() -> vec3 { vec3(0f, 1f, 0f) }
|
||||
#[inline(always)] pure fn vec3_unit_z() -> vec3 { vec3(0f, 0f, 1f) }
|
||||
#[inline(always)] pure fn vec3_identity() -> vec3 { vec3(1f, 1f, 1f) }
|
||||
const vec3_zero :vec3 = vec3 { data: [ 0f, 0f, 0f ] };
|
||||
const vec3_unit_x :vec3 = vec3 { data: [ 1f, 0f, 0f ] };
|
||||
const vec3_unit_y :vec3 = vec3 { data: [ 0f, 1f, 0f ] };
|
||||
const vec3_unit_z :vec3 = vec3 { data: [ 0f, 0f, 1f ] };
|
||||
const vec3_identity :vec3 = vec3 { data: [ 1f, 1f, 1f ] };
|
||||
|
||||
//
|
||||
// Constructor
|
||||
|
@ -259,7 +276,7 @@ impl vec3: Vector3<float> {
|
|||
|
||||
impl vec3: Vector<float> {
|
||||
#[inline(always)]
|
||||
pure fn dim() -> uint { 3 }
|
||||
static pure fn dim() -> uint { 3 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> float {
|
||||
|
@ -364,24 +381,27 @@ impl vec3: Vector<float> {
|
|||
|
||||
#[inline(always)]
|
||||
pure fn abs() -> vec3 {
|
||||
vec3(abs(self[0]),
|
||||
abs(self[1]),
|
||||
abs(self[2]))
|
||||
vec3(self[0].abs(),
|
||||
self[1].abs(),
|
||||
self[2].abs())
|
||||
}
|
||||
|
||||
// #[inline(always)]
|
||||
// pure fn min(&&other:vec3) -> vec3 {
|
||||
// vec3(fmin(self[0], other[0]),
|
||||
// fmin(self[1], other[1]),
|
||||
// fmin(self[2], other[2]))
|
||||
// }
|
||||
#[inline(always)]
|
||||
pure fn min(&&other:vec3) -> vec3 {
|
||||
vec3(min(self[0], other[0]),
|
||||
min(self[1], other[1]),
|
||||
min(self[2], other[2]))
|
||||
}
|
||||
|
||||
// #[inline(always)]
|
||||
// pure fn max(&&other:vec3) -> vec3 {
|
||||
// vec3(fmin(self[0], other[0]),
|
||||
// fmin(self[1], other[1]),
|
||||
// fmin(self[2], other[2]))
|
||||
// }
|
||||
#[inline(always)]
|
||||
pure fn max(&&other:vec3) -> vec3 {
|
||||
vec3(max(self[0], other[0]),
|
||||
max(self[1], other[1]),
|
||||
max(self[2], other[2]))
|
||||
}
|
||||
|
||||
#[inline(always)] static pure fn zero() -> vec3 { vec3(1f, 1f, 1f) }
|
||||
#[inline(always)] static pure fn identity() -> vec3 { vec3(1f, 1f, 1f) }
|
||||
}
|
||||
|
||||
impl vec3: ToStr {
|
||||
|
@ -400,15 +420,12 @@ impl vec3: ToStr {
|
|||
//
|
||||
struct vec4 { data:[float * 4] }
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
#[inline(always)] pure fn vec4_zero() -> vec4 { vec4(0f, 0f, 0f, 0f) }
|
||||
#[inline(always)] pure fn vec4_unit_x() -> vec4 { vec4(1f, 0f, 0f, 0f) }
|
||||
#[inline(always)] pure fn vec4_unit_y() -> vec4 { vec4(0f, 1f, 0f, 0f) }
|
||||
#[inline(always)] pure fn vec4_unit_z() -> vec4 { vec4(0f, 0f, 1f, 0f) }
|
||||
#[inline(always)] pure fn vec4_unit_w() -> vec4 { vec4(0f, 0f, 0f, 1f) }
|
||||
#[inline(always)] pure fn vec4_identity() -> vec4 { vec4(1f, 1f, 1f, 1f) }
|
||||
const vec4_zero :vec4 = vec4 { data: [ 0f, 0f, 0f, 0f ] };
|
||||
const vec4_unit_x :vec4 = vec4 { data: [ 1f, 0f, 0f, 0f ] };
|
||||
const vec4_unit_y :vec4 = vec4 { data: [ 0f, 1f, 0f, 0f ] };
|
||||
const vec4_unit_z :vec4 = vec4 { data: [ 0f, 0f, 1f, 0f ] };
|
||||
const vec4_unit_w :vec4 = vec4 { data: [ 0f, 0f, 0f, 1f ] };
|
||||
const vec4_identity :vec4 = vec4 { data: [ 1f, 1f, 1f, 1f ] };
|
||||
|
||||
//
|
||||
// Constructor
|
||||
|
@ -427,7 +444,7 @@ impl vec4: Vector4<float> {
|
|||
|
||||
impl vec4: Vector<float> {
|
||||
#[inline(always)]
|
||||
pure fn dim() -> uint { 4 }
|
||||
static pure fn dim() -> uint { 4 }
|
||||
|
||||
#[inline(always)]
|
||||
pure fn index(&&i: uint) -> float {
|
||||
|
@ -542,27 +559,30 @@ impl vec4: Vector<float> {
|
|||
|
||||
#[inline(always)]
|
||||
pure fn abs() -> vec4 {
|
||||
vec4(abs(self[0]),
|
||||
abs(self[1]),
|
||||
abs(self[2]),
|
||||
abs(self[3]))
|
||||
vec4(self[0].abs(),
|
||||
self[1].abs(),
|
||||
self[2].abs(),
|
||||
self[3].abs())
|
||||
}
|
||||
|
||||
// #[inline(always)]
|
||||
// pure fn min(&&other:vec4) -> vec4 {
|
||||
// vec4(fmin(self[0], other[0]),
|
||||
// fmin(self[1], other[1]),
|
||||
// fmin(self[2], other[2]),
|
||||
// fmin(self[3], other[3]))
|
||||
// }
|
||||
#[inline(always)]
|
||||
pure fn min(&&other:vec4) -> vec4 {
|
||||
vec4(min(self[0], other[0]),
|
||||
min(self[1], other[1]),
|
||||
min(self[2], other[2]),
|
||||
min(self[3], other[3]))
|
||||
}
|
||||
|
||||
// #[inline(always)]
|
||||
// pure fn max(&&other:vec4) -> vec4 {
|
||||
// vec4(fmin(self[0], other[0]),
|
||||
// fmin(self[1], other[1]),
|
||||
// fmin(self[2], other[2]),
|
||||
// fmin(self[3], other[3]))
|
||||
// }
|
||||
#[inline(always)]
|
||||
pure fn max(&&other:vec4) -> vec4 {
|
||||
vec4(max(self[0], other[0]),
|
||||
max(self[1], other[1]),
|
||||
max(self[2], other[2]),
|
||||
max(self[3], other[3]))
|
||||
}
|
||||
|
||||
#[inline(always)] static pure fn zero() -> vec4 { vec4(1f, 1f, 1f, 1f) }
|
||||
#[inline(always)] static pure fn identity() -> vec4 { vec4(1f, 1f, 1f, 1f) }
|
||||
}
|
||||
|
||||
impl vec4: ToStr {
|
||||
|
|
1
test/test_math.rs
Normal file
1
test/test_math.rs
Normal file
|
@ -0,0 +1 @@
|
|||
// TODO
|
|
@ -9,6 +9,7 @@ use std;
|
|||
use om3d;
|
||||
|
||||
mod test_mat;
|
||||
mod test_math;
|
||||
mod test_projection;
|
||||
mod test_quat;
|
||||
mod test_vec;
|
|
@ -5,6 +5,8 @@ import om3d::vec::*;
|
|||
|
||||
#[test]
|
||||
fn test_vec2() {
|
||||
// assert vec2::dim == 2;
|
||||
|
||||
let a = vec2 { data: [ 1f, 2f ] };
|
||||
let b = vec2 { data: [ 3f, 4f ] };
|
||||
let f1 = 1.5f;
|
||||
|
@ -12,10 +14,10 @@ fn test_vec2() {
|
|||
|
||||
assert a == vec2(1f, 2f);
|
||||
|
||||
assert vec2_zero() == vec2(0f, 0f);
|
||||
assert vec2_unit_x() == vec2(1f, 0f);
|
||||
assert vec2_unit_y() == vec2(0f, 1f);
|
||||
assert vec2_identity() == vec2(1f, 1f);
|
||||
assert vec2_zero == vec2(0f, 0f);
|
||||
assert vec2_unit_x == vec2(1f, 0f);
|
||||
assert vec2_unit_y == vec2(0f, 1f);
|
||||
assert vec2_identity == vec2(1f, 1f);
|
||||
|
||||
assert a[0] == 1f;
|
||||
assert a[1] == 2f;
|
||||
|
@ -45,13 +47,15 @@ fn test_vec2() {
|
|||
let f3 = 0.75f;
|
||||
|
||||
assert c.lerp(d, f3) == vec2(0.250f, -0.250f);
|
||||
assert c.abs() == vec2(2.0f, 1.0f);
|
||||
|
||||
// TODO min, max
|
||||
assert c.abs() == vec2( 2.0f, 1.0f);
|
||||
assert c.min(d) == vec2(-2.0f, -1.0f);
|
||||
assert c.max(d) == vec2( 1.0f, 0.0f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec3() {
|
||||
// assert vec3::dim == 3;
|
||||
|
||||
let a = vec3 { data: [ 1f, 2f, 3f ] };
|
||||
let b = vec3 { data: [ 4f, 5f, 6f ] };
|
||||
let f1 = 1.5f;
|
||||
|
@ -59,11 +63,11 @@ fn test_vec3() {
|
|||
|
||||
assert a == vec3(1f, 2f, 3f);
|
||||
|
||||
assert vec3_zero() == vec3(0f, 0f, 0f);
|
||||
assert vec3_unit_x() == vec3(1f, 0f, 0f);
|
||||
assert vec3_unit_y() == vec3(0f, 1f, 0f);
|
||||
assert vec3_unit_z() == vec3(0f, 0f, 1f);
|
||||
assert vec3_identity() == vec3(1f, 1f, 1f);
|
||||
assert vec3_zero == vec3(0f, 0f, 0f);
|
||||
assert vec3_unit_x == vec3(1f, 0f, 0f);
|
||||
assert vec3_unit_y == vec3(0f, 1f, 0f);
|
||||
assert vec3_unit_z == vec3(0f, 0f, 1f);
|
||||
assert vec3_identity == vec3(1f, 1f, 1f);
|
||||
|
||||
assert a[0] == 1f;
|
||||
assert a[1] == 2f;
|
||||
|
@ -97,13 +101,15 @@ fn test_vec3() {
|
|||
let f3 = 0.75f;
|
||||
|
||||
assert c.lerp(d, f3) == vec3(0.250f, -0.250f, 0.625f);
|
||||
assert c.abs() == vec3(2.0f, 1.0f, 1.0f);
|
||||
|
||||
// TODO min, max
|
||||
assert c.abs() == vec3( 2.0f, 1.0f, 1.0f);
|
||||
assert c.min(d) == vec3(-2.0f, -1.0f, 0.5f);
|
||||
assert c.max(d) == vec3( 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_vec4() {
|
||||
// assert vec4::dim == 4;
|
||||
|
||||
let a = vec4 { data: [ 1f, 2f, 3f, 4f ] };
|
||||
let b = vec4 { data: [ 5f, 6f, 7f, 8f ] };
|
||||
let f1 = 1.5f;
|
||||
|
@ -111,12 +117,12 @@ fn test_vec4() {
|
|||
|
||||
assert a == vec4(1f, 2f, 3f, 4f);
|
||||
|
||||
assert vec4_zero() == vec4(0f, 0f, 0f, 0f);
|
||||
assert vec4_unit_x() == vec4(1f, 0f, 0f, 0f);
|
||||
assert vec4_unit_y() == vec4(0f, 1f, 0f, 0f);
|
||||
assert vec4_unit_z() == vec4(0f, 0f, 1f, 0f);
|
||||
assert vec4_unit_w() == vec4(0f, 0f, 0f, 1f);
|
||||
assert vec4_identity() == vec4(1f, 1f, 1f, 1f);
|
||||
assert vec4_zero == vec4(0f, 0f, 0f, 0f);
|
||||
assert vec4_unit_x == vec4(1f, 0f, 0f, 0f);
|
||||
assert vec4_unit_y == vec4(0f, 1f, 0f, 0f);
|
||||
assert vec4_unit_z == vec4(0f, 0f, 1f, 0f);
|
||||
assert vec4_unit_w == vec4(0f, 0f, 0f, 1f);
|
||||
assert vec4_identity == vec4(1f, 1f, 1f, 1f);
|
||||
|
||||
assert a[0] == 1f;
|
||||
assert a[1] == 2f;
|
||||
|
@ -152,7 +158,7 @@ fn test_vec4() {
|
|||
let f3 = 0.75f;
|
||||
|
||||
assert c.lerp(d, f3) == vec4(0.250f, -0.250f, 0.625f, 1.250f);
|
||||
assert c.abs() == vec4(2.0f, 1.0f, 1.0f, 2.0f);
|
||||
|
||||
// TODO min, max
|
||||
assert c.abs() == vec4( 2.0f, 1.0f, 1.0f, 2.0f);
|
||||
assert c.min(d) == vec4(-2.0f, -1.0f, 0.5f, 1.0f);
|
||||
assert c.max(d) == vec4( 1.0f, 0.0f, 1.0f, 2.0f);
|
||||
}
|
Loading…
Reference in a new issue