From 4c2f301561b3ceace1bad6660dde0d0d71c657d9 Mon Sep 17 00:00:00 2001 From: Brendan Zabarauskas Date: Mon, 25 Apr 2016 08:59:33 +1000 Subject: [PATCH] Add Vector1 and Point1 structs --- src/lib.rs | 4 ++-- src/macros.rs | 6 ++++-- src/point.rs | 27 ++++++++++++++++++++++++++- src/vector.rs | 38 +++++++++++++++++++++++++++++++++++--- 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 0d5c0fc..17fc201 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,11 +62,11 @@ pub use structure::*; pub use matrix::{Matrix2, Matrix3, Matrix4}; 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 euler::Euler; -pub use point::{Point2, Point3}; +pub use point::{Point1, Point2, Point3}; pub use rotation::*; pub use transform::*; diff --git a/src/macros.rs b/src/macros.rs index f1fb8b6..d9e54de 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -129,9 +129,11 @@ macro_rules! impl_assignment_operator { } macro_rules! fold_array { + (&$method:ident, { $x:expr }) => { *$x }; (&$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, $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, $z:expr }) => { $x.$method($y).$method($z) }; ($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> { #[inline] 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> { #[inline] fn from(v: $Tuple) -> $ArrayN<$S> { - match v { ($($field),+) => $ArrayN { $($field: $field),+ } } + match v { ($($field),+,) => $ArrayN { $($field: $field),+ } } } } diff --git a/src/point.rs b/src/point.rs index 350e197..31cde6b 100644 --- a/src/point.rs +++ b/src/point.rs @@ -27,7 +27,16 @@ use structure::*; use approx::ApproxEq; 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 { + pub x: S, +} /// A point in 2-dimensional space. /// @@ -50,6 +59,12 @@ pub struct Point3 { pub z: S, } +impl Point1 { + #[inline] + pub fn new(x: S) -> Point1 { + Point1 { x: x } + } +} impl Point2 { #[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!(Point3 { x, y, z }, Vector3, 3); +impl_fixed_array_conversions!(Point1 { x: 0 }, 1); impl_fixed_array_conversions!(Point2 { x: 0, y: 1 }, 2); impl_fixed_array_conversions!(Point3 { x: 0, y: 1, z: 2 }, 3); +impl_tuple_conversions!(Point1 { x }, (S,)); impl_tuple_conversions!(Point2 { x, y }, (S, S)); impl_tuple_conversions!(Point3 { x, y, z }, (S, S, S)); +impl fmt::Debug for Point1 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "Point1 ")); + <[S; 1] as fmt::Debug>::fmt(self.as_ref(), f) + } +} + impl fmt::Debug for Point2 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "Point2 ")); diff --git a/src/vector.rs b/src/vector.rs index 17cdb60..8bcffa6 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -25,6 +25,16 @@ use angle::Rad; use approx::ApproxEq; 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 { + /// The x component of the vector. + pub x: S, +} + /// A 2-dimensional vector. /// /// 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!(Vector3 { x, y, z }, 3, vec3); impl_vector!(Vector4 { x, y, z, w }, 4, vec4); +impl_fixed_array_conversions!(Vector1 { x: 0 }, 1); impl_fixed_array_conversions!(Vector2 { x: 0, y: 1 }, 2); impl_fixed_array_conversions!(Vector3 { x: 0, y: 1, z: 2 }, 3); impl_fixed_array_conversions!(Vector4 { x: 0, y: 1, z: 2, w: 3 }, 4); +impl_tuple_conversions!(Vector1 { x }, (S,)); impl_tuple_conversions!(Vector2 { x, y }, (S, S)); impl_tuple_conversions!(Vector3 { x, y, z }, (S, S, S)); impl_tuple_conversions!(Vector4 { x, y, z, w }, (S, S, S, S)); -/// Operations specific to numeric two-dimensional vectors. +impl Vector1 { + /// A unit vector in the `x` direction. + #[inline] + pub fn unit_x() -> Vector1 { + Vector1::new(S::one()) + } +} + impl Vector2 { /// A unit vector in the `x` direction. #[inline] @@ -300,7 +320,6 @@ impl Vector2 { } } -/// Operations specific to numeric three-dimensional vectors. impl Vector3 { /// A unit vector in the `x` direction. #[inline] @@ -343,7 +362,6 @@ impl Vector3 { } } -/// Operations specific to numeric four-dimensional vectors. impl Vector4 { /// A unit vector in the `x` direction. #[inline] @@ -396,6 +414,13 @@ pub fn dot(a: V, b: V) -> V::Scalar where V::dot(a, b) } +impl InnerSpace for Vector1 { + #[inline] + fn dot(self, other: Vector1) -> S { + Vector1::mul_element_wise(self, other).sum() + } +} + impl InnerSpace for Vector2 { #[inline] fn dot(self, other: Vector2) -> S { @@ -427,6 +452,13 @@ impl InnerSpace for Vector4 { } } +impl fmt::Debug for Vector1 { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + try!(write!(f, "Vector1 ")); + <[S; 1] as fmt::Debug>::fmt(self.as_ref(), f) + } +} + impl fmt::Debug for Vector2 { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(write!(f, "Vector2 "));