Add swap methods

This commit is contained in:
Brendan Zabarauskas 2012-12-04 17:58:03 +10:00
parent 969e57591d
commit 0b9af30b38
4 changed files with 231 additions and 0 deletions

View file

@ -28,6 +28,16 @@ pub trait Matrix<T,V>: Dimensional<V>, ToPtr<T>, Eq, Neg<self> {
*/ */
pure fn row(&self, i: uint) -> V; 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 * Returns the identity matrix
*/ */
@ -250,6 +260,30 @@ pub impl<T:Copy Float> Mat2<T>: Matrix<T, Vec2<T>> {
self[1][i]) 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 * Returns the multiplicative identity matrix
* ~~~ * ~~~
@ -578,6 +612,33 @@ pub impl<T:Copy Float> Mat3<T>: Matrix<T, Vec3<T>> {
self[2][i]) 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 * Returns the multiplicative identity matrix
* ~~~ * ~~~
@ -998,6 +1059,36 @@ pub impl<T:Copy Float Sign> Mat4<T>: Matrix<T, Vec4<T>> {
self[3][i]) 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 * Returns the multiplicative identity matrix
* ~~~ * ~~~

View file

@ -33,6 +33,16 @@ fn test_Mat2() {
assert a.col(0) == Vec2::new(1f, 3f); assert a.col(0) == Vec2::new(1f, 3f);
assert a.col(1) == Vec2::new(2f, 4f); 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, assert Mat2::identity() == Mat2::new(1f, 0f,
0f, 1f); 0f, 1f);
mut_a.to_identity(); mut_a.to_identity();
@ -156,6 +166,26 @@ fn test_Mat3() {
assert a.col(1) == Vec3::new(2f, 5f, 8f); assert a.col(1) == Vec3::new(2f, 5f, 8f);
assert a.col(2) == Vec3::new(3f, 6f, 9f); 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, assert Mat3::identity() == Mat3::new(1f, 0f, 0f,
0f, 1f, 0f, 0f, 1f, 0f,
0f, 0f, 1f); 0f, 0f, 1f);
@ -311,6 +341,26 @@ fn test_Mat4() {
assert a.col(2) == Vec4::new(3f, 7f, 11f, 15f); assert a.col(2) == Vec4::new(3f, 7f, 11f, 15f);
assert a.col(3) == Vec4::new(4f, 8f, 12f, 16f); 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, assert Mat4::identity() == Mat4::new(1f, 0f, 0f, 0f,
0f, 1f, 0f, 0f, 0f, 1f, 0f, 0f,
0f, 0f, 1f, 0f, 0f, 0f, 1f, 0f,

View file

@ -20,6 +20,11 @@ fn test_Vec2() {
// assert Vec2::unit_y() == Vec2::new(0f, 1f); // assert Vec2::unit_y() == Vec2::new(0f, 1f);
// assert Vec2::identity() == Vec2::new(1f, 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.x == 1f;
assert a.y == 2f; assert a.y == 2f;
assert a[0] == 1f; assert a[0] == 1f;
@ -82,6 +87,16 @@ fn test_Vec3() {
// assert Vec3::unit_z() == Vec3::new(0f, 0f, 1f); // assert Vec3::unit_z() == Vec3::new(0f, 0f, 1f);
// assert Vec3::identity() == Vec3::new(1f, 1f, 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.x == 1f;
assert a.y == 2f; assert a.y == 2f;
assert a.z == 3f; assert a.z == 3f;
@ -142,6 +157,16 @@ fn test_Vec4() {
assert Vec4::new(1f, 2f, 3f, 4f) == a; assert Vec4::new(1f, 2f, 3f, 4f) == a;
// assert Vec4::from_value(1f32) == Vec4::new(1f32, 1f32, 1f32, 1f32); // 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::zero() == Vec4::new(0f, 0f, 0f, 0f);
// assert Vec4::unit_x() == Vec4::new(1f, 0f, 0f, 0f); // assert Vec4::unit_x() == Vec4::new(1f, 0f, 0f, 0f);
// assert Vec4::unit_y() == Vec4::new(0f, 1f, 0f, 0f); // assert Vec4::unit_y() == Vec4::new(0f, 1f, 0f, 0f);

View file

@ -17,6 +17,11 @@ use num::kinds::Number;
pub trait Vector<T>: Dimensional<T>, ToPtr<T>, Eq, DefaultEq { pub trait Vector<T>: Dimensional<T>, ToPtr<T>, Eq, DefaultEq {
/// Construct the vector from a single value, copying it to each component /// Construct the vector from a single value, copying it to each component
static pure fn from_value(value: T) -> self; 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<T:Copy> Vec2<T>: Vector<T> {
static pure fn from_value(value: T) -> Vec2<T> { static pure fn from_value(value: T) -> Vec2<T> {
Vec2::new(value, value) 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<T> Vec2<T>: Dimensional<T> { pub impl<T> Vec2<T>: Dimensional<T> {
@ -330,6 +353,26 @@ pub impl<T:Copy> Vec3<T>: Vector<T> {
static pure fn from_value(value: T) -> Vec3<T> { static pure fn from_value(value: T) -> Vec3<T> {
Vec3::new(value, value, value) 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<T> Vec3<T>: Dimensional<T> { pub impl<T> Vec3<T>: Dimensional<T> {
@ -511,6 +554,28 @@ pub impl<T:Copy> Vec4<T>: Vector<T> {
static pure fn from_value(value: T) -> Vec4<T> { static pure fn from_value(value: T) -> Vec4<T> {
Vec4::new(value, value, value, value) 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<T> Vec4<T>: Dimensional<T> { pub impl<T> Vec4<T>: Dimensional<T> {