Complete the documentation for Translation.

This commit is contained in:
sebcrozet 2018-10-28 07:33:14 +01:00 committed by Sébastien Crozet
parent 1dd6bcce6a
commit 96db8e564a
6 changed files with 120 additions and 25 deletions

View File

@ -52,7 +52,7 @@ where
{ {
#[inline] #[inline]
fn clone(&self) -> Self { fn clone(&self) -> Self {
Translation::from_vector(self.vector.clone()) Translation::from(self.vector.clone())
} }
} }
@ -99,7 +99,7 @@ where
where Des: Deserializer<'a> { where Des: Deserializer<'a> {
let matrix = VectorN::<N, D>::deserialize(deserializer)?; let matrix = VectorN::<N, D>::deserialize(deserializer)?;
Ok(Translation::from_vector(matrix)) Ok(Translation::from(matrix))
} }
} }
@ -108,18 +108,49 @@ where DefaultAllocator: Allocator<N, D>
{ {
/// Creates a new translation from the given vector. /// Creates a new translation from the given vector.
#[inline] #[inline]
#[deprecated(note = "Use `::from` instead.")]
pub fn from_vector(vector: VectorN<N, D>) -> Translation<N, D> { pub fn from_vector(vector: VectorN<N, D>) -> Translation<N, D> {
Translation { vector: vector } Translation { vector: vector }
} }
/// Inverts `self`. /// Inverts `self`.
///
/// # Example
/// ```
/// # use nalgebra::{Translation2, Translation3};
/// let t = Translation3::new(1.0, 2.0, 3.0);
/// assert_eq!(t * t.inverse(), Translation3::identity());
/// assert_eq!(t.inverse() * t, Translation3::identity());
///
/// // Work in all dimensions.
/// let t = Translation2::new(1.0, 2.0);
/// assert_eq!(t * t.inverse(), Translation2::identity());
/// assert_eq!(t.inverse() * t, Translation2::identity());
/// ```
#[inline] #[inline]
pub fn inverse(&self) -> Translation<N, D> pub fn inverse(&self) -> Translation<N, D>
where N: ClosedNeg { where N: ClosedNeg {
Translation::from_vector(-&self.vector) Translation::from(-&self.vector)
} }
/// Converts this translation into its equivalent homogeneous transformation matrix. /// Converts this translation into its equivalent homogeneous transformation matrix.
///
/// # Example
/// ```
/// # use nalgebra::{Translation2, Translation3, Matrix3, Matrix4};
/// let t = Translation3::new(10.0, 20.0, 30.0);
/// let expected = Matrix4::new(1.0, 0.0, 0.0, 10.0,
/// 0.0, 1.0, 0.0, 20.0,
/// 0.0, 0.0, 1.0, 30.0,
/// 0.0, 0.0, 0.0, 1.0);
/// assert_eq!(t.to_homogeneous(), expected);
///
/// let t = Translation2::new(10.0, 20.0);
/// let expected = Matrix3::new(1.0, 0.0, 10.0,
/// 0.0, 1.0, 20.0,
/// 0.0, 0.0, 1.0);
/// assert_eq!(t.to_homogeneous(), expected);
/// ```
#[inline] #[inline]
pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>> pub fn to_homogeneous(&self) -> MatrixN<N, DimNameSum<D, U1>>
where where
@ -135,6 +166,23 @@ where DefaultAllocator: Allocator<N, D>
} }
/// Inverts `self` in-place. /// Inverts `self` in-place.
///
/// # Example
/// ```
/// # use nalgebra::{Translation2, Translation3};
/// let t = Translation3::new(1.0, 2.0, 3.0);
/// let mut inv_t = Translation3::new(1.0, 2.0, 3.0);
/// inv_t.inverse_mut();
/// assert_eq!(t * inv_t, Translation3::identity());
/// assert_eq!(inv_t * t, Translation3::identity());
///
/// // Work in all dimensions.
/// let t = Translation2::new(1.0, 2.0);
/// let mut inv_t = Translation2::new(1.0, 2.0);
/// inv_t.inverse_mut();
/// assert_eq!(t * inv_t, Translation2::identity());
/// assert_eq!(inv_t * t, Translation2::identity());
/// ```
#[inline] #[inline]
pub fn inverse_mut(&mut self) pub fn inverse_mut(&mut self)
where N: ClosedNeg { where N: ClosedNeg {

View File

@ -183,16 +183,16 @@ where DefaultAllocator: Allocator<N, D>
#[inline] #[inline]
fn from_vector(v: VectorN<N, D>) -> Option<Self> { fn from_vector(v: VectorN<N, D>) -> Option<Self> {
Some(Self::from_vector(v)) Some(Self::from(v))
} }
#[inline] #[inline]
fn powf(&self, n: N) -> Option<Self> { fn powf(&self, n: N) -> Option<Self> {
Some(Self::from_vector(&self.vector * n)) Some(Self::from(&self.vector * n))
} }
#[inline] #[inline]
fn translation_between(a: &Point<N, D>, b: &Point<N, D>) -> Option<Self> { fn translation_between(a: &Point<N, D>, b: &Point<N, D>) -> Option<Self> {
Some(Self::from_vector(b - a)) Some(Self::from(b - a))
} }
} }

View File

@ -1,9 +1,21 @@
use base::dimension::{U2, U3}; use base::dimension::{U1, U2, U3, U4, U5, U6};
use geometry::Translation; use geometry::Translation;
/// A 1-dimensional translation.
pub type Translation1<N> = Translation<N, U1>;
/// A 2-dimensional translation. /// A 2-dimensional translation.
pub type Translation2<N> = Translation<N, U2>; pub type Translation2<N> = Translation<N, U2>;
/// A 3-dimensional translation. /// A 3-dimensional translation.
pub type Translation3<N> = Translation<N, U3>; pub type Translation3<N> = Translation<N, U3>;
/// A 4-dimensional translation.
pub type Translation4<N> = Translation<N, U4>;
/// A 5-dimensional translation.
pub type Translation5<N> = Translation<N, U5>;
/// A 6-dimensional translation.
pub type Translation6<N> = Translation<N, U6>;

View File

@ -18,10 +18,23 @@ use geometry::Translation;
impl<N: Scalar + Zero, D: DimName> Translation<N, D> impl<N: Scalar + Zero, D: DimName> Translation<N, D>
where DefaultAllocator: Allocator<N, D> where DefaultAllocator: Allocator<N, D>
{ {
/// Creates a new square identity rotation of the given `dimension`. /// Creates a new identity translation.
///
/// # Example
/// ```
/// # use nalgebra::{Point2, Point3, Translation2, Translation3};
/// let t = Translation2::identity();
/// let p = Point2::new(1.0, 2.0);
/// assert_eq!(t * p, p);
///
/// // Works in all dimensions.
/// let t = Translation3::identity();
/// let p = Point3::new(1.0, 2.0, 3.0);
/// assert_eq!(t * p, p);
/// ```
#[inline] #[inline]
pub fn identity() -> Translation<N, D> { pub fn identity() -> Translation<N, D> {
Self::from_vector(VectorN::<N, D>::from_element(N::zero())) Self::from(VectorN::<N, D>::from_element(N::zero()))
} }
} }
@ -41,7 +54,7 @@ where
{ {
#[inline] #[inline]
fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation<N, D> { fn sample<'a, G: Rng + ?Sized>(&self, rng: &'a mut G) -> Translation<N, D> {
Translation::from_vector(rng.gen::<VectorN<N, D>>()) Translation::from(rng.gen::<VectorN<N, D>>())
} }
} }
@ -53,7 +66,7 @@ where
{ {
#[inline] #[inline]
fn arbitrary<G: Gen>(rng: &mut G) -> Self { fn arbitrary<G: Gen>(rng: &mut G) -> Self {
Self::from_vector(Arbitrary::arbitrary(rng)) Self::from(Arbitrary::arbitrary(rng))
} }
} }
@ -63,23 +76,32 @@ where
* *
*/ */
macro_rules! componentwise_constructors_impl( macro_rules! componentwise_constructors_impl(
($($D: ty, $($args: ident:$irow: expr),*);* $(;)*) => {$( ($($doc: expr; $D: ty, $($args: ident:$irow: expr),*);* $(;)*) => {$(
impl<N: Scalar> Translation<N, $D> impl<N: Scalar> Translation<N, $D>
where DefaultAllocator: Allocator<N, $D> { where DefaultAllocator: Allocator<N, $D> {
/// Initializes this matrix from its components. #[doc = "Initializes this translation from its components."]
#[doc = "# Example\n```"]
#[doc = $doc]
#[doc = "```"]
#[inline] #[inline]
pub fn new($($args: N),*) -> Self { pub fn new($($args: N),*) -> Self {
Self::from_vector(VectorN::<N, $D>::new($($args),*)) Self::from(VectorN::<N, $D>::new($($args),*))
} }
} }
)*} )*}
); );
componentwise_constructors_impl!( componentwise_constructors_impl!(
"# use nalgebra::Translation1;\nlet t = Translation1::new(1.0);\nassert!(t.vector.x == 1.0);";
U1, x:0; U1, x:0;
"# use nalgebra::Translation2;\nlet t = Translation2::new(1.0, 2.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0);";
U2, x:0, y:1; U2, x:0, y:1;
"# use nalgebra::Translation3;\nlet t = Translation3::new(1.0, 2.0, 3.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0);";
U3, x:0, y:1, z:2; U3, x:0, y:1, z:2;
"# use nalgebra::Translation4;\nlet t = Translation4::new(1.0, 2.0, 3.0, 4.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0);";
U4, x:0, y:1, z:2, w:3; U4, x:0, y:1, z:2, w:3;
"# use nalgebra::Translation5;\nlet t = Translation5::new(1.0, 2.0, 3.0, 4.0, 5.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0);";
U5, x:0, y:1, z:2, w:3, a:4; U5, x:0, y:1, z:2, w:3, a:4;
"# use nalgebra::Translation6;\nlet t = Translation6::new(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);\nassert!(t.vector.x == 1.0 && t.vector.y == 2.0 && t.vector.z == 3.0 && t.vector.w == 4.0 && t.vector.a == 5.0 && t.vector.b == 6.0);";
U6, x:0, y:1, z:2, w:3, a:4, b:5; U6, x:0, y:1, z:2, w:3, a:4, b:5;
); );

View File

@ -28,7 +28,7 @@ where
{ {
#[inline] #[inline]
fn to_superset(&self) -> Translation<N2, D> { fn to_superset(&self) -> Translation<N2, D> {
Translation::from_vector(self.vector.to_superset()) Translation::from(self.vector.to_superset())
} }
#[inline] #[inline]
@ -38,7 +38,9 @@ where
#[inline] #[inline]
unsafe fn from_superset_unchecked(rot: &Translation<N2, D>) -> Self { unsafe fn from_superset_unchecked(rot: &Translation<N2, D>) -> Self {
Translation::from_vector(rot.vector.to_subset_unchecked()) Translation {
vector: rot.vector.to_subset_unchecked(),
}
} }
} }
@ -145,7 +147,9 @@ where
#[inline] #[inline]
unsafe fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self { unsafe fn from_superset_unchecked(m: &MatrixN<N2, DimNameSum<D, U1>>) -> Self {
let t = m.fixed_slice::<D, U1>(0, D::dim()); let t = m.fixed_slice::<D, U1>(0, D::dim());
Self::from_vector(::convert_unchecked(t.into_owned())) Self {
vector: ::convert_unchecked(t.into_owned()),
}
} }
} }
@ -159,3 +163,12 @@ where
t.to_homogeneous() t.to_homogeneous()
} }
} }
impl<N: Scalar, D: DimName> From<VectorN<N, D>> for Translation<N, D>
where DefaultAllocator: Allocator<N, D>
{
#[inline]
fn from(vector: VectorN<N, D>) -> Self {
Translation { vector }
}
}

View File

@ -13,44 +13,44 @@ use geometry::{Point, Translation};
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(&self.vector + &right.vector); 'a, 'b); Translation::from(&self.vector + &right.vector); 'a, 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(&self.vector + right.vector); 'a); Translation::from(&self.vector + right.vector); 'a);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(self.vector + &right.vector); 'b); Translation::from(self.vector + &right.vector); 'b);
add_sub_impl!(Mul, mul, ClosedAdd; add_sub_impl!(Mul, mul, ClosedAdd;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(self.vector + right.vector); ); Translation::from(self.vector + right.vector); );
// Translation ÷ Translation // Translation ÷ Translation
// FIXME: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method? // FIXME: instead of calling inverse explicitly, could we just add a `mul_tr` or `mul_inv` method?
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(&self.vector - &right.vector); 'a, 'b); Translation::from(&self.vector - &right.vector); 'a, 'b);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: &'a Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(&self.vector - right.vector); 'a); Translation::from(&self.vector - right.vector); 'a);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: &'b Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(self.vector - &right.vector); 'b); Translation::from(self.vector - &right.vector); 'b);
add_sub_impl!(Div, div, ClosedSub; add_sub_impl!(Div, div, ClosedSub;
(D, U1), (D, U1) -> (D) for D: DimName; (D, U1), (D, U1) -> (D) for D: DimName;
self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>; self: Translation<N, D>, right: Translation<N, D>, Output = Translation<N, D>;
Translation::from_vector(self.vector - right.vector); ); Translation::from(self.vector - right.vector); );
// Translation × Point // Translation × Point
// FIXME: we don't handle properly non-zero origins here. Do we want this to be the intended // FIXME: we don't handle properly non-zero origins here. Do we want this to be the intended