Merge pull request #96 from atheriel/vecmap

Add a map() method for vectors.
This commit is contained in:
Brendan Zabarauskas 2014-07-05 19:24:12 -07:00
commit 61a6810324
6 changed files with 64 additions and 0 deletions

View file

@ -42,6 +42,9 @@ pub trait Array1<Element: Copy> {
fn replace_i(&mut self, i: uint, src: Element) -> Element {
mem::replace(self.mut_i(i), src)
}
/// Apply a function to each element.
fn map(&mut self, op: |Element| -> Element) -> Self;
}
/// A column-major array
@ -93,4 +96,7 @@ pub trait Array2<Column: Array1<Element>, Row: Array1<Element>, Element: Copy> {
let (bc, br) = b;
unsafe { ptr::swap(self.mut_cr(ac, ar), self.mut_cr(bc, br)) };
}
/// Apply a function to each column.
fn map(&mut self, op: |&Column| -> Column) -> Self;
}

View file

@ -416,6 +416,13 @@ impl<S: Copy> Array2<Vector2<S>, Vector2<S>, S> for Matrix2<S> {
self.mut_c(0).swap_i(a, b);
self.mut_c(1).swap_i(a, b);
}
#[inline]
fn map(&mut self, op: |&Vector2<S>| -> Vector2<S>) -> Matrix2<S> {
self.x = op(&self.x);
self.y = op(&self.y);
*self
}
}
impl<S: Copy> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
@ -450,6 +457,14 @@ impl<S: Copy> Array2<Vector3<S>, Vector3<S>, S> for Matrix3<S> {
self.mut_c(1).swap_i(a, b);
self.mut_c(2).swap_i(a, b);
}
#[inline]
fn map(&mut self, op: |&Vector3<S>| -> Vector3<S>) -> Matrix3<S> {
self.x = op(&self.x);
self.y = op(&self.y);
self.z = op(&self.z);
*self
}
}
impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
@ -486,6 +501,15 @@ impl<S: Copy> Array2<Vector4<S>, Vector4<S>, S> for Matrix4<S> {
self.mut_c(2).swap_i(a, b);
self.mut_c(3).swap_i(a, b);
}
#[inline]
fn map(&mut self, op: |&Vector4<S>| -> Vector4<S>) -> Matrix4<S> {
self.x = op(&self.x);
self.y = op(&self.y);
self.z = op(&self.z);
self.w = op(&self.w);
*self
}
}
impl<S: BaseFloat> Matrix<S, Vector2<S>> for Matrix2<S> {

View file

@ -120,6 +120,13 @@ impl<S: BaseNum> Array1<S> for Point2<S> {
let slice: &'a mut [S, ..2] = unsafe { mem::transmute(self) };
&mut slice[i]
}
#[inline]
fn map(&mut self, op: |S| -> S) -> Point2<S> {
self.x = op(self.x);
self.y = op(self.y);
*self
}
}
impl<S: BaseNum> Point<S, Vector2<S>> for Point2<S> {
@ -238,6 +245,14 @@ impl<S: BaseNum> Array1<S> for Point3<S> {
let slice: &'a mut [S, ..3] = unsafe { mem::transmute(self) };
&mut slice[i]
}
#[inline]
fn map(&mut self, op: |S| -> S) -> Point3<S> {
self.x = op(self.x);
self.y = op(self.y);
self.z = op(self.z);
*self
}
}
impl<S: BaseNum> Point<S, Vector3<S>> for Point3<S> {

View file

@ -55,6 +55,15 @@ impl<S: Copy> Array1<S> for Quaternion<S> {
let slice: &'a mut [S, ..4] = unsafe { mem::transmute(self) };
&mut slice[i]
}
#[inline]
fn map(&mut self, op: |S| -> S) -> Quaternion<S> {
self.s = op(self.s);
self.v.x = op(self.v.x);
self.v.y = op(self.v.y);
self.v.z = op(self.v.z);
*self
}
}
impl<S: BaseFloat> Quaternion<S> {

View file

@ -14,6 +14,7 @@
// limitations under the License.
use cgmath::angle::*;
use cgmath::array::*;
use cgmath::vector::*;
use cgmath::approx::ApproxEq;
@ -157,3 +158,9 @@ fn test_normalize() {
assert!(Vector3::new(2.0f64, 3.0f64, 6.0f64).normalize().approx_eq( &Vector3::new(2.0/7.0, 3.0/7.0, 6.0/7.0) ));
assert!(Vector4::new(1.0f64, 2.0f64, 4.0f64, 10.0f64).normalize().approx_eq( &Vector4::new(1.0/11.0, 2.0/11.0, 4.0/11.0, 10.0/11.0) ));
}
#[test]
fn test_map() {
assert_eq!(Vector3::new(7.12f64, 3.8f64, -6.98f64).map(|x| x.floor()), Vector3::new(7.0f64, 3.0f64, -7.0f64));
assert_eq!(Vector3::new(7.12f64, 3.8f64, -6.98f64).map(|x| x.max(0.0f64)), Vector3::new(7.12f64, 3.8f64, 0.0f64));
}

View file

@ -144,6 +144,9 @@ macro_rules! vec(
let slice: &'a mut [S, ..$n] = unsafe { mem::transmute(self) };
&mut slice[i]
}
#[inline]
fn map(&mut self, op: |S| -> S) -> $Self<S> { $(self.$field = op(self.$field);)+ *self }
}
impl<S: BaseNum> Vector<S> for $Self<S> {