From 0b9af30b386a3074441ce6e02187e43a1827f17e Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Tue, 4 Dec 2012 17:58:03 +1000 Subject: [PATCH] Add swap methods --- src/mat.rs | 91 ++++++++++++++++++++++++++++++++++++++++++++ src/test/test_mat.rs | 50 ++++++++++++++++++++++++ src/test/test_vec.rs | 25 ++++++++++++ src/vec.rs | 65 +++++++++++++++++++++++++++++++ 4 files changed, 231 insertions(+) diff --git a/src/mat.rs b/src/mat.rs index 5681ea0..eba21d6 100644 --- a/src/mat.rs +++ b/src/mat.rs @@ -28,6 +28,16 @@ pub trait Matrix: Dimensional, ToPtr, Eq, Neg { */ pure fn row(&self, i: uint) -> V; + /** + * Swap two columns of the matrix in place + */ + fn swap_cols(&mut self, a: uint, b: uint); + + /** + * Swap two rows of the matrix in place + */ + fn swap_rows(&mut self, a: uint, b: uint); + /** * Returns the identity matrix */ @@ -250,6 +260,30 @@ pub impl Mat2: Matrix> { self[1][i]) } + #[inline(always)] + fn swap_cols(&mut self, a: uint, b: uint) { + let addr_a = + match a { + 0 => &mut self.x, + 1 => &mut self.y, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 1 but found %u", a)) + }; + let addr_b = + match b { + 0 => &mut self.x, + 1 => &mut self.y, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 1 but found %u", b)) + }; + + util::swap(addr_a, addr_b); + } + + #[inline(always)] + fn swap_rows(&mut self, a: uint, b: uint) { + self.x.swap(a, b); + self.y.swap(a, b); + } + /** * Returns the multiplicative identity matrix * ~~~ @@ -578,6 +612,33 @@ pub impl Mat3: Matrix> { self[2][i]) } + #[inline(always)] + fn swap_cols(&mut self, a: uint, b: uint) { + let addr_a = + match a { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 2 but found %u", a)) + }; + let addr_b = + match b { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 2 but found %u", b)) + }; + + util::swap(addr_a, addr_b); + } + + #[inline(always)] + fn swap_rows(&mut self, a: uint, b: uint) { + self.x.swap(a, b); + self.y.swap(a, b); + self.z.swap(a, b); + } + /** * Returns the multiplicative identity matrix * ~~~ @@ -998,6 +1059,36 @@ pub impl Mat4: Matrix> { self[3][i]) } + #[inline(always)] + fn swap_cols(&mut self, a: uint, b: uint) { + let addr_a = + match a { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + 3 => &mut self.w, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 3 but found %u", a)) + }; + let addr_b = + match b { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + 3 => &mut self.w, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 3 but found %u", b)) + }; + + util::swap(addr_a, addr_b); + } + + #[inline(always)] + fn swap_rows(&mut self, a: uint, b: uint) { + self.x.swap(a, b); + self.y.swap(a, b); + self.z.swap(a, b); + self.w.swap(a, b); + } + /** * Returns the multiplicative identity matrix * ~~~ diff --git a/src/test/test_mat.rs b/src/test/test_mat.rs index 1dc9c05..39d7c50 100644 --- a/src/test/test_mat.rs +++ b/src/test/test_mat.rs @@ -33,6 +33,16 @@ fn test_Mat2() { assert a.col(0) == Vec2::new(1f, 3f); assert a.col(1) == Vec2::new(2f, 4f); + mut_a.swap_cols(0, 1); + assert mut_a.col(0) == a.col(1); + assert mut_a.col(1) == a.col(0); + mut_a = a; + + mut_a.swap_rows(0, 1); + assert mut_a.row(0) == a.row(1); + assert mut_a.row(1) == a.row(0); + mut_a = a; + assert Mat2::identity() == Mat2::new(1f, 0f, 0f, 1f); mut_a.to_identity(); @@ -156,6 +166,26 @@ fn test_Mat3() { assert a.col(1) == Vec3::new(2f, 5f, 8f); assert a.col(2) == Vec3::new(3f, 6f, 9f); + mut_a.swap_cols(0, 2); + assert mut_a.col(0) == a.col(2); + assert mut_a.col(2) == a.col(0); + mut_a = a; + + mut_a.swap_cols(1, 2); + assert mut_a.col(1) == a.col(2); + assert mut_a.col(2) == a.col(1); + mut_a = a; + + mut_a.swap_rows(0, 2); + assert mut_a.row(0) == a.row(2); + assert mut_a.row(2) == a.row(0); + mut_a = a; + + mut_a.swap_rows(1, 2); + assert mut_a.row(1) == a.row(2); + assert mut_a.row(2) == a.row(1); + mut_a = a; + assert Mat3::identity() == Mat3::new(1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f); @@ -311,6 +341,26 @@ fn test_Mat4() { assert a.col(2) == Vec4::new(3f, 7f, 11f, 15f); assert a.col(3) == Vec4::new(4f, 8f, 12f, 16f); + mut_a.swap_cols(0, 3); + assert mut_a.col(0) == a.col(3); + assert mut_a.col(3) == a.col(0); + mut_a = a; + + mut_a.swap_cols(1, 2); + assert mut_a.col(1) == a.col(2); + assert mut_a.col(2) == a.col(1); + mut_a = a; + + mut_a.swap_rows(0, 3); + assert mut_a.row(0) == a.row(3); + assert mut_a.row(3) == a.row(0); + mut_a = a; + + mut_a.swap_rows(1, 2); + assert mut_a.row(1) == a.row(2); + assert mut_a.row(2) == a.row(1); + mut_a = a; + assert Mat4::identity() == Mat4::new(1f, 0f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1f, 0f, diff --git a/src/test/test_vec.rs b/src/test/test_vec.rs index 1d2b94d..7b4dcf7 100644 --- a/src/test/test_vec.rs +++ b/src/test/test_vec.rs @@ -20,6 +20,11 @@ fn test_Vec2() { // assert Vec2::unit_y() == Vec2::new(0f, 1f); // assert Vec2::identity() == Vec2::new(1f, 1f); + let mut mut_a = a; + mut_a.swap(0, 1); + assert mut_a[0] == a[1]; + assert mut_a[1] == a[0]; + assert a.x == 1f; assert a.y == 2f; assert a[0] == 1f; @@ -82,6 +87,16 @@ fn test_Vec3() { // assert Vec3::unit_z() == Vec3::new(0f, 0f, 1f); // assert Vec3::identity() == Vec3::new(1f, 1f, 1f); + let mut mut_a = a; + mut_a.swap(0, 2); + assert mut_a[0] == a[2]; + assert mut_a[2] == a[0]; + + mut_a = a; + mut_a.swap(1, 2); + assert mut_a[1] == a[2]; + assert mut_a[2] == a[1]; + assert a.x == 1f; assert a.y == 2f; assert a.z == 3f; @@ -142,6 +157,16 @@ fn test_Vec4() { assert Vec4::new(1f, 2f, 3f, 4f) == a; // assert Vec4::from_value(1f32) == Vec4::new(1f32, 1f32, 1f32, 1f32); + let mut mut_a = a; + mut_a.swap(0, 3); + assert mut_a[0] == a[3]; + assert mut_a[3] == a[0]; + + mut_a = a; + mut_a.swap(1, 2); + assert mut_a[1] == a[2]; + assert mut_a[2] == a[1]; + // assert Vec4::zero() == Vec4::new(0f, 0f, 0f, 0f); // assert Vec4::unit_x() == Vec4::new(1f, 0f, 0f, 0f); // assert Vec4::unit_y() == Vec4::new(0f, 1f, 0f, 0f); diff --git a/src/vec.rs b/src/vec.rs index 773d0b6..2ea253e 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -17,6 +17,11 @@ use num::kinds::Number; pub trait Vector: Dimensional, ToPtr, Eq, DefaultEq { /// Construct the vector from a single value, copying it to each component static pure fn from_value(value: T) -> self; + + /** + * Swap two components of the vector in place + */ + fn swap(&mut self, a: uint, b: uint); } /** @@ -167,6 +172,24 @@ pub impl Vec2: Vector { static pure fn from_value(value: T) -> Vec2 { Vec2::new(value, value) } + + #[inline(always)] + fn swap(&mut self, a: uint, b: uint) { + let addr_a = + match a { + 0 => &mut self.x, + 1 => &mut self.y, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 1, but found %u", a)) + }; + let addr_b = + match b { + 0 => &mut self.x, + 1 => &mut self.y, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 3, but found %u", b)) + }; + + util::swap(addr_a, addr_b); + } } pub impl Vec2: Dimensional { @@ -330,6 +353,26 @@ pub impl Vec3: Vector { static pure fn from_value(value: T) -> Vec3 { Vec3::new(value, value, value) } + + #[inline(always)] + fn swap(&mut self, a: uint, b: uint) { + let addr_a = + match a { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 2, but found %u", a)) + }; + let addr_b = + match b { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 2, but found %u", b)) + }; + + util::swap(addr_a, addr_b); + } } pub impl Vec3: Dimensional { @@ -511,6 +554,28 @@ pub impl Vec4: Vector { static pure fn from_value(value: T) -> Vec4 { Vec4::new(value, value, value, value) } + + #[inline(always)] + fn swap(&mut self, a: uint, b: uint) { + let addr_a = + match a { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + 3 => &mut self.w, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 3 but found %u", a)) + }; + let addr_b = + match b { + 0 => &mut self.x, + 1 => &mut self.y, + 2 => &mut self.z, + 3 => &mut self.w, + _ => fail(fmt!("index out of bounds: expected an index from 0 to 3 but found %u", b)) + }; + + util::swap(addr_a, addr_b); + } } pub impl Vec4: Dimensional {