From 9f3a6325d7661ad8717b21378ff204d25d320411 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 10 Sep 2012 12:55:15 +1000 Subject: [PATCH] Improve generic traits --- src/mat.rs | 27 +++++++++++++-------------- src/math.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/quat.rs | 4 ++-- src/vec.rs | 17 ++++++++--------- 4 files changed, 72 insertions(+), 27 deletions(-) diff --git a/src/mat.rs b/src/mat.rs index 11d2729..076263d 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -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> { +trait Matrix { pure fn rows() -> uint; pure fn cols() -> uint; pure fn is_col_major() -> bool; @@ -43,8 +42,8 @@ trait Matrix> { // // 3x3 Matrix // -trait Matrix3> { - pure fn scale(&&vec:V) -> self; +trait Matrix3 { + pure fn scale(&&vec:V3) -> self; pure fn to_mat4() -> mat4; pure fn to_quat() -> quat; } @@ -52,9 +51,9 @@ trait Matrix3> { // // 4x4 Matrix // -trait Matrix4> { - pure fn scale(&&vec:vec3) -> self; // I don't like the use of `vec3` here - pure fn translate(&&vec:vec3) -> self; +trait Matrix4 { + 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 { } } -impl mat3: Matrix3 { +impl mat3: Matrix3 { #[inline(always)] pure fn scale(&&vec:vec3) -> mat3 { self.mul_m(mat3(vec.x(), 0f, 0f, @@ -412,28 +411,28 @@ impl mat3: Matrix3 { 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 { } } -impl mat4: Matrix4 { +impl mat4: Matrix4 { #[inline(always)] pure fn scale(&&vec:vec3) -> mat4 { self.mul_m(mat4(vec.x(), 0f, 0f, 0f, diff --git a/src/math.rs b/src/math.rs index e913471..c2aa1a1 100644 --- a/src/math.rs +++ b/src/math.rs @@ -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(&&a:T, &&b:T) -> T { +pure fn min(&&a:T, &&b:T) -> T { if a < b { a } else { b } } +// +// Max +// #[inline(always)] -pure fn max(&&a:T, &&b:T) -> T { +pure fn max(&&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) + } } \ No newline at end of file diff --git a/src/quat.rs b/src/quat.rs index 264ccb1..9a5168c 100644 --- a/src/quat.rs +++ b/src/quat.rs @@ -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 { +trait Quaternion { pure fn dim() -> uint; pure fn index(&&index:uint) -> T; diff --git a/src/vec.rs b/src/vec.rs index dd03f60..bd89440 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -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 { +trait Vector { static pure fn dim() -> uint; pure fn index(&&index:uint) -> T; @@ -48,7 +47,7 @@ trait Vector { -trait Vector2 { +trait Vector2 { // This is where I wish rust had properties ;) pure fn x() -> T; pure fn y() -> T; @@ -58,7 +57,7 @@ trait Vector2 { // static pure fn unit_y() -> self; } -trait Vector3 { +trait Vector3 { pure fn x() -> T; pure fn y() -> T; pure fn z() -> T; @@ -72,7 +71,7 @@ trait Vector3 { fn cross(&&other:self) -> self; } -trait Vector4 { +trait Vector4 { pure fn x() -> T; pure fn y() -> T; pure fn z() -> T; @@ -195,7 +194,7 @@ impl vec2: Vector { #[inline(always)] pure fn magnitude() -> float { - sqrt(self.magnitude2()) + self.magnitude2().sqrt() } #[inline(always)] @@ -365,7 +364,7 @@ impl vec3: Vector { #[inline(always)] pure fn magnitude() -> float { - sqrt(self.magnitude2()) + self.magnitude2().sqrt() } #[inline(always)] @@ -543,7 +542,7 @@ impl vec4: Vector { #[inline(always)] pure fn magnitude() -> float { - sqrt(self.magnitude2()) + self.magnitude2().sqrt() } #[inline(always)]