Add Vector1 and Point1 structs

This commit is contained in:
Brendan Zabarauskas 2016-04-25 08:59:33 +10:00
parent 87fcb62653
commit 4c2f301561
4 changed files with 67 additions and 8 deletions

View file

@ -62,11 +62,11 @@ pub use structure::*;
pub use matrix::{Matrix2, Matrix3, Matrix4}; pub use matrix::{Matrix2, Matrix3, Matrix4};
pub use quaternion::Quaternion; pub use quaternion::Quaternion;
pub use vector::{Vector2, Vector3, Vector4, dot, vec2, vec3, vec4}; pub use vector::{Vector1, Vector2, Vector3, Vector4, dot, vec1, vec2, vec3, vec4};
pub use angle::{Deg, Rad, deg, rad}; pub use angle::{Deg, Rad, deg, rad};
pub use euler::Euler; pub use euler::Euler;
pub use point::{Point2, Point3}; pub use point::{Point1, Point2, Point3};
pub use rotation::*; pub use rotation::*;
pub use transform::*; pub use transform::*;

View file

@ -129,9 +129,11 @@ macro_rules! impl_assignment_operator {
} }
macro_rules! fold_array { macro_rules! fold_array {
(&$method:ident, { $x:expr }) => { *$x };
(&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) }; (&$method:ident, { $x:expr, $y:expr }) => { $x.$method(&$y) };
(&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) }; (&$method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method(&$y).$method(&$z) };
(&$method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method(&$y).$method(&$z).$method(&$w) }; (&$method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method(&$y).$method(&$z).$method(&$w) };
($method:ident, { $x:expr }) => { $x };
($method:ident, { $x:expr, $y:expr }) => { $x.$method($y) }; ($method:ident, { $x:expr, $y:expr }) => { $x.$method($y) };
($method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method($y).$method($z) }; ($method:ident, { $x:expr, $y:expr, $z:expr }) => { $x.$method($y).$method($z) };
($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method($y).$method($z).$method($w) }; ($method:ident, { $x:expr, $y:expr, $z:expr, $w:expr }) => { $x.$method($y).$method($z).$method($w) };
@ -191,7 +193,7 @@ macro_rules! impl_tuple_conversions {
impl<$S> Into<$Tuple> for $ArrayN<$S> { impl<$S> Into<$Tuple> for $ArrayN<$S> {
#[inline] #[inline]
fn into(self) -> $Tuple { fn into(self) -> $Tuple {
match self { $ArrayN { $($field),+ } => ($($field),+) } match self { $ArrayN { $($field),+ } => ($($field),+,) }
} }
} }
@ -212,7 +214,7 @@ macro_rules! impl_tuple_conversions {
impl<$S> From<$Tuple> for $ArrayN<$S> { impl<$S> From<$Tuple> for $ArrayN<$S> {
#[inline] #[inline]
fn from(v: $Tuple) -> $ArrayN<$S> { fn from(v: $Tuple) -> $ArrayN<$S> {
match v { ($($field),+) => $ArrayN { $($field: $field),+ } } match v { ($($field),+,) => $ArrayN { $($field: $field),+ } }
} }
} }

View file

@ -27,7 +27,16 @@ use structure::*;
use approx::ApproxEq; use approx::ApproxEq;
use num::{BaseNum, BaseFloat}; use num::{BaseNum, BaseFloat};
use vector::{Vector2, Vector3, Vector4}; use vector::{Vector1, Vector2, Vector3, Vector4};
/// A point in 1-dimensional space.
///
/// This type is marked as `#[repr(C, packed)]`.
#[repr(C, packed)]
#[derive(PartialEq, Eq, Copy, Clone, Hash, RustcEncodable, RustcDecodable)]
pub struct Point1<S> {
pub x: S,
}
/// A point in 2-dimensional space. /// A point in 2-dimensional space.
/// ///
@ -50,6 +59,12 @@ pub struct Point3<S> {
pub z: S, pub z: S,
} }
impl<S: BaseNum> Point1<S> {
#[inline]
pub fn new(x: S) -> Point1<S> {
Point1 { x: x }
}
}
impl<S: BaseNum> Point2<S> { impl<S: BaseNum> Point2<S> {
#[inline] #[inline]
@ -217,15 +232,25 @@ macro_rules! impl_scalar_ops {
}; };
} }
impl_point!(Point1 { x }, Vector1, 1);
impl_point!(Point2 { x, y }, Vector2, 2); impl_point!(Point2 { x, y }, Vector2, 2);
impl_point!(Point3 { x, y, z }, Vector3, 3); impl_point!(Point3 { x, y, z }, Vector3, 3);
impl_fixed_array_conversions!(Point1<S> { x: 0 }, 1);
impl_fixed_array_conversions!(Point2<S> { x: 0, y: 1 }, 2); impl_fixed_array_conversions!(Point2<S> { x: 0, y: 1 }, 2);
impl_fixed_array_conversions!(Point3<S> { x: 0, y: 1, z: 2 }, 3); impl_fixed_array_conversions!(Point3<S> { x: 0, y: 1, z: 2 }, 3);
impl_tuple_conversions!(Point1<S> { x }, (S,));
impl_tuple_conversions!(Point2<S> { x, y }, (S, S)); impl_tuple_conversions!(Point2<S> { x, y }, (S, S));
impl_tuple_conversions!(Point3<S> { x, y, z }, (S, S, S)); impl_tuple_conversions!(Point3<S> { x, y, z }, (S, S, S));
impl<S: fmt::Debug> fmt::Debug for Point1<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "Point1 "));
<[S; 1] as fmt::Debug>::fmt(self.as_ref(), f)
}
}
impl<S: fmt::Debug> fmt::Debug for Point2<S> { impl<S: fmt::Debug> fmt::Debug for Point2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "Point2 ")); try!(write!(f, "Point2 "));

View file

@ -25,6 +25,16 @@ use angle::Rad;
use approx::ApproxEq; use approx::ApproxEq;
use num::{BaseNum, BaseFloat, PartialOrd}; use num::{BaseNum, BaseFloat, PartialOrd};
/// A 1-dimensional vector.
///
/// This type is marked as `#[repr(C, packed)]`.
#[repr(C, packed)]
#[derive(PartialEq, Eq, Copy, Clone, Hash, RustcEncodable, RustcDecodable)]
pub struct Vector1<S> {
/// The x component of the vector.
pub x: S,
}
/// A 2-dimensional vector. /// A 2-dimensional vector.
/// ///
/// This type is marked as `#[repr(C, packed)]`. /// This type is marked as `#[repr(C, packed)]`.
@ -260,19 +270,29 @@ macro_rules! impl_scalar_ops {
}; };
} }
impl_vector!(Vector1 { x }, 1, vec1);
impl_vector!(Vector2 { x, y }, 2, vec2); impl_vector!(Vector2 { x, y }, 2, vec2);
impl_vector!(Vector3 { x, y, z }, 3, vec3); impl_vector!(Vector3 { x, y, z }, 3, vec3);
impl_vector!(Vector4 { x, y, z, w }, 4, vec4); impl_vector!(Vector4 { x, y, z, w }, 4, vec4);
impl_fixed_array_conversions!(Vector1<S> { x: 0 }, 1);
impl_fixed_array_conversions!(Vector2<S> { x: 0, y: 1 }, 2); impl_fixed_array_conversions!(Vector2<S> { x: 0, y: 1 }, 2);
impl_fixed_array_conversions!(Vector3<S> { x: 0, y: 1, z: 2 }, 3); impl_fixed_array_conversions!(Vector3<S> { x: 0, y: 1, z: 2 }, 3);
impl_fixed_array_conversions!(Vector4<S> { x: 0, y: 1, z: 2, w: 3 }, 4); impl_fixed_array_conversions!(Vector4<S> { x: 0, y: 1, z: 2, w: 3 }, 4);
impl_tuple_conversions!(Vector1<S> { x }, (S,));
impl_tuple_conversions!(Vector2<S> { x, y }, (S, S)); impl_tuple_conversions!(Vector2<S> { x, y }, (S, S));
impl_tuple_conversions!(Vector3<S> { x, y, z }, (S, S, S)); impl_tuple_conversions!(Vector3<S> { x, y, z }, (S, S, S));
impl_tuple_conversions!(Vector4<S> { x, y, z, w }, (S, S, S, S)); impl_tuple_conversions!(Vector4<S> { x, y, z, w }, (S, S, S, S));
/// Operations specific to numeric two-dimensional vectors. impl<S: BaseNum> Vector1<S> {
/// A unit vector in the `x` direction.
#[inline]
pub fn unit_x() -> Vector1<S> {
Vector1::new(S::one())
}
}
impl<S: BaseNum> Vector2<S> { impl<S: BaseNum> Vector2<S> {
/// A unit vector in the `x` direction. /// A unit vector in the `x` direction.
#[inline] #[inline]
@ -300,7 +320,6 @@ impl<S: BaseNum> Vector2<S> {
} }
} }
/// Operations specific to numeric three-dimensional vectors.
impl<S: BaseNum> Vector3<S> { impl<S: BaseNum> Vector3<S> {
/// A unit vector in the `x` direction. /// A unit vector in the `x` direction.
#[inline] #[inline]
@ -343,7 +362,6 @@ impl<S: BaseNum> Vector3<S> {
} }
} }
/// Operations specific to numeric four-dimensional vectors.
impl<S: BaseNum> Vector4<S> { impl<S: BaseNum> Vector4<S> {
/// A unit vector in the `x` direction. /// A unit vector in the `x` direction.
#[inline] #[inline]
@ -396,6 +414,13 @@ pub fn dot<V: InnerSpace>(a: V, b: V) -> V::Scalar where
V::dot(a, b) V::dot(a, b)
} }
impl<S: BaseFloat> InnerSpace for Vector1<S> {
#[inline]
fn dot(self, other: Vector1<S>) -> S {
Vector1::mul_element_wise(self, other).sum()
}
}
impl<S: BaseFloat> InnerSpace for Vector2<S> { impl<S: BaseFloat> InnerSpace for Vector2<S> {
#[inline] #[inline]
fn dot(self, other: Vector2<S>) -> S { fn dot(self, other: Vector2<S>) -> S {
@ -427,6 +452,13 @@ impl<S: BaseFloat> InnerSpace for Vector4<S> {
} }
} }
impl<S: fmt::Debug> fmt::Debug for Vector1<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "Vector1 "));
<[S; 1] as fmt::Debug>::fmt(self.as_ref(), f)
}
}
impl<S: fmt::Debug> fmt::Debug for Vector2<S> { impl<S: fmt::Debug> fmt::Debug for Vector2<S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "Vector2 ")); try!(write!(f, "Vector2 "));