Improve generic traits

This commit is contained in:
Brendan Zabarauskas 2012-09-10 12:55:15 +10:00
parent fda5fcecc3
commit 9f3a6325d7
4 changed files with 72 additions and 27 deletions

View file

@ -2,15 +2,14 @@ import std::cmp::FuzzyEq;
import cmp::Ord;
import num::Num;
// import to_str::ToStr;
import math::Sqrt;
import quat::quat;
import vec::*;
// TODO: Unittests! I've probably made lots of mistakes...
//
// NxN Matrix
//
trait Matrix<T:Num Ord FuzzyEq, V:Vector<T>> {
trait Matrix<T, V> {
pure fn rows() -> uint;
pure fn cols() -> uint;
pure fn is_col_major() -> bool;
@ -43,8 +42,8 @@ trait Matrix<T:Num Ord FuzzyEq, V:Vector<T>> {
//
// 3x3 Matrix
//
trait Matrix3<T:Num Ord FuzzyEq, V:Vector<T>> {
pure fn scale(&&vec:V) -> self;
trait Matrix3<V3> {
pure fn scale(&&vec:V3) -> self;
pure fn to_mat4() -> mat4;
pure fn to_quat() -> quat;
}
@ -52,9 +51,9 @@ trait Matrix3<T:Num Ord FuzzyEq, V:Vector<T>> {
//
// 4x4 Matrix
//
trait Matrix4<T:Num Ord FuzzyEq, V:Vector<T>> {
pure fn scale(&&vec:vec3) -> self; // I don't like the use of `vec3` here
pure fn translate(&&vec:vec3) -> self;
trait Matrix4<V3, V4> {
pure fn scale(&&vec:V3) -> self; // I don't like the use of `vec3` here
pure fn translate(&&vec:V3) -> self;
}
@ -387,7 +386,7 @@ impl mat3: Matrix<float, vec3> {
}
}
impl mat3: Matrix3<float, vec3> {
impl mat3: Matrix3<vec3> {
#[inline(always)]
pure fn scale(&&vec:vec3) -> mat3 {
self.mul_m(mat3(vec.x(), 0f, 0f,
@ -412,28 +411,28 @@ impl mat3: Matrix3<float, vec3> {
let trace:float = self[0][0] + self[1][1] + self[2][2];
if trace >= 0f {
s = sqrt(trace + 1f);
s = (trace + 1f).sqrt();
w = 0.5 * s;
s = 0.5 / s;
x = self[1][2] - self[2][1] * s;
y = self[2][0] - self[0][2] * s;
z = self[0][1] - self[1][0] * s;
} else if (self[0][0] > self[1][1]) && (self[0][0] > self[2][2]) {
s = sqrt(1f + self[0][0] - self[1][1] - self[2][2]);
s = (1f + self[0][0] - self[1][1] - self[2][2]).sqrt();
w = 0.5 * s;
s = 0.5 / s;
x = self[0][1] - self[1][0] * s;
y = self[2][0] - self[0][2] * s;
z = self[1][2] - self[2][1] * s;
} else if self[1][1] > self[2][2] {
s = sqrt(1f + self[1][1] - self[0][0] - self[2][2]);
s = (1f + self[1][1] - self[0][0] - self[2][2]).sqrt();
w = 0.5 * s;
s = 0.5 / s;
x = self[0][1] - self[1][0] * s;
y = self[1][2] - self[2][1] * s;
z = self[2][0] - self[0][2] * s;
} else {
s = sqrt(1f + self[2][2] - self[0][0] - self[1][1]);
s = (1f + self[2][2] - self[0][0] - self[1][1]).sqrt();
w = 0.5 * s;
s = 0.5 / s;
x = self[2][0] - self[0][2] * s;
@ -658,7 +657,7 @@ impl mat4: Matrix<float, vec4> {
}
}
impl mat4: Matrix4<float, vec4> {
impl mat4: Matrix4<vec3, vec4> {
#[inline(always)]
pure fn scale(&&vec:vec3) -> mat4 {
self.mul_m(mat4(vec.x(), 0f, 0f, 0f,

View file

@ -1,5 +1,11 @@
import cmp::Ord;
import float::sqrt;
import f32::sqrt;
import f64::sqrt;
//
// Abs
//
trait Abs {
pure fn abs() -> self;
}
@ -36,14 +42,55 @@ impl f64: Abs {
}
}
//
// Min
//
#[inline(always)]
pure fn min<T:copy Ord>(&&a:T, &&b:T) -> T {
pure fn min<T:Copy Ord>(&&a:T, &&b:T) -> T {
if a < b { a }
else { b }
}
//
// Max
//
#[inline(always)]
pure fn max<T:copy Ord>(&&a:T, &&b:T) -> T {
pure fn max<T:Copy Ord>(&&a:T, &&b:T) -> T {
if a > b { a }
else { b }
}
//
// Sqrt
//
trait Sqrt {
pure fn sqrt() -> self;
}
// impl int: Sqrt {
// #[inline(always)]
// pure fn sqrt() -> int {
// sqrt(self)
// }
// }
impl float: Sqrt {
#[inline(always)]
pure fn sqrt() -> float {
float::sqrt(self)
}
}
impl f32: Sqrt {
#[inline(always)]
pure fn sqrt() -> f32 {
f32::sqrt(self)
}
}
impl f64: Sqrt {
#[inline(always)]
pure fn sqrt() -> f64 {
f64::sqrt(self)
}
}

View file

@ -6,12 +6,12 @@ import to_str::ToStr;
import mat::{mat3, mat4};
import vec::vec3;
// TODO: Unittests! I've probably made lots of mistakes...
// TODO: Unittests
//
// Quaternion
//
trait Quaternion<T:Num Ord FuzzyEq> {
trait Quaternion<T> {
pure fn dim() -> uint;
pure fn index(&&index:uint) -> T;

View file

@ -1,14 +1,13 @@
import std::cmp::FuzzyEq;
import cmp::Ord;
import num::Num;
import float::sqrt;
import math::{Abs, min, max};
import math::{Abs, min, max, Sqrt};
import to_str::ToStr;
//
// N-dimensional Vector
//
trait Vector<T:Num Ord FuzzyEq> {
trait Vector<T> {
static pure fn dim() -> uint;
pure fn index(&&index:uint) -> T;
@ -48,7 +47,7 @@ trait Vector<T:Num Ord FuzzyEq> {
trait Vector2<T:Num Ord FuzzyEq> {
trait Vector2<T> {
// This is where I wish rust had properties ;)
pure fn x() -> T;
pure fn y() -> T;
@ -58,7 +57,7 @@ trait Vector2<T:Num Ord FuzzyEq> {
// static pure fn unit_y() -> self;
}
trait Vector3<T:Num Ord FuzzyEq> {
trait Vector3<T> {
pure fn x() -> T;
pure fn y() -> T;
pure fn z() -> T;
@ -72,7 +71,7 @@ trait Vector3<T:Num Ord FuzzyEq> {
fn cross(&&other:self) -> self;
}
trait Vector4<T:Num Ord FuzzyEq> {
trait Vector4<T> {
pure fn x() -> T;
pure fn y() -> T;
pure fn z() -> T;
@ -195,7 +194,7 @@ impl vec2: Vector<float> {
#[inline(always)]
pure fn magnitude() -> float {
sqrt(self.magnitude2())
self.magnitude2().sqrt()
}
#[inline(always)]
@ -365,7 +364,7 @@ impl vec3: Vector<float> {
#[inline(always)]
pure fn magnitude() -> float {
sqrt(self.magnitude2())
self.magnitude2().sqrt()
}
#[inline(always)]
@ -543,7 +542,7 @@ impl vec4: Vector<float> {
#[inline(always)]
pure fn magnitude() -> float {
sqrt(self.magnitude2())
self.magnitude2().sqrt()
}
#[inline(always)]