nalgebra/src/structs/iso.rs

160 lines
5.3 KiB
Rust
Raw Normal View History

//! Isometric transformations.
#![allow(missing_docs)]
2015-01-04 16:37:56 +08:00
use std::ops::{Add, Sub, Mul};
2015-01-04 05:48:10 +08:00
2014-10-15 03:37:44 +08:00
use std::rand::{Rand, Rng};
use structs::mat::{Mat3, Mat4, Mat5};
use traits::structure::{Cast, Dim, Col, BaseFloat, BaseNum, One};
use traits::operations::{Inv, ApproxEq};
use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation,
Translate, Translation, ToHomogeneous};
use structs::vec::{Vec1, Vec2, Vec3, Vec4};
use structs::pnt::{Pnt2, Pnt3, Pnt4};
use structs::rot::{Rot2, Rot3, Rot4};
#[cfg(feature="arbitrary")]
use quickcheck::{Arbitrary, Gen};
/// Two dimensional isometry.
///
/// This is the composition of a rotation followed by a translation.
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
2015-01-04 05:48:10 +08:00
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Show, Copy)]
pub struct Iso2<N> {
/// The rotation applicable by this isometry.
2014-04-04 02:52:52 +08:00
pub rotation: Rot2<N>,
/// The translation applicable by this isometry.
2014-04-04 02:52:52 +08:00
pub translation: Vec2<N>
}
/// Three dimensional isometry.
///
/// This is the composition of a rotation followed by a translation.
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
2015-01-04 05:48:10 +08:00
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Show, Copy)]
pub struct Iso3<N> {
/// The rotation applicable by this isometry.
2014-04-04 02:52:52 +08:00
pub rotation: Rot3<N>,
/// The translation applicable by this isometry.
2014-04-04 02:52:52 +08:00
pub translation: Vec3<N>
}
/// Four dimensional isometry.
///
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
2015-01-04 05:48:10 +08:00
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Show, Copy)]
pub struct Iso4<N> {
/// The rotation applicable by this isometry.
2014-04-04 02:52:52 +08:00
pub rotation: Rot4<N>,
/// The translation applicable by this isometry.
2014-04-04 02:52:52 +08:00
pub translation: Vec4<N>
}
impl<N: Clone + BaseFloat> Iso3<N> {
2013-10-09 03:00:25 +08:00
/// Reorient and translate this transformation such that its local `x` axis points to a given
/// direction. Note that the usually known `look_at` function does the same thing but with the
/// `z` axis. See `look_at_z` for that.
///
/// # Arguments
/// * eye - The new translation of the transformation.
/// * at - The point to look at. `at - eye` is the direction the matrix `x` axis will be
/// aligned with.
/// * up - Vector pointing up. The only requirement of this parameter is to not be colinear
/// with `at`. Non-colinearity is not checked.
pub fn look_at(&mut self, eye: &Pnt3<N>, at: &Pnt3<N>, up: &Vec3<N>) {
2013-10-09 03:00:25 +08:00
self.rotation.look_at(&(*at - *eye), up);
self.translation = eye.as_vec().clone();
2013-10-09 03:00:25 +08:00
}
/// Reorient and translate this transformation such that its local `z` axis points to a given
2014-05-21 19:08:04 +08:00
/// direction.
2013-10-09 03:00:25 +08:00
///
/// # Arguments
/// * eye - The new translation of the transformation.
/// * at - The point to look at. `at - eye` is the direction the matrix `x` axis will be
/// aligned with
/// * up - Vector pointing `up`. The only requirement of this parameter is to not be colinear
/// with `at`. Non-colinearity is not checked.
pub fn look_at_z(&mut self, eye: &Pnt3<N>, at: &Pnt3<N>, up: &Vec3<N>) {
2013-10-09 03:00:25 +08:00
self.rotation.look_at_z(&(*at - *eye), up);
self.translation = eye.as_vec().clone();
2013-10-09 03:00:25 +08:00
}
}
impl<N> Iso4<N> {
// XXX remove that when iso_impl works for Iso4
/// Creates a new isometry from a rotation matrix and a vector.
#[inline]
pub fn new_with_rotmat(translation: Vec4<N>, rotation: Rot4<N>) -> Iso4<N> {
Iso4 {
rotation: rotation,
translation: translation
}
}
}
iso_impl!(Iso2, Rot2, Vec2, Vec1);
rotation_matrix_impl!(Iso2, Rot2, Vec2, Vec1);
rotation_impl!(Iso2, Rot2, Vec1);
dim_impl!(Iso2, 2);
one_impl!(Iso2);
absolute_rotate_impl!(Iso2, Vec2);
rand_impl!(Iso2);
approx_eq_impl!(Iso2);
to_homogeneous_impl!(Iso2, Mat3);
inv_impl!(Iso2);
transform_impl!(Iso2, Pnt2);
transformation_impl!(Iso2);
rotate_impl!(Iso2, Vec2);
translation_impl!(Iso2, Vec2);
translate_impl!(Iso2, Pnt2);
iso_mul_iso_impl!(Iso2);
iso_mul_pnt_impl!(Iso2, Pnt2);
pnt_mul_iso_impl!(Iso2, Pnt2);
arbitrary_iso_impl!(Iso2);
iso_impl!(Iso3, Rot3, Vec3, Vec3);
rotation_matrix_impl!(Iso3, Rot3, Vec3, Vec3);
rotation_impl!(Iso3, Rot3, Vec3);
dim_impl!(Iso3, 3);
one_impl!(Iso3);
absolute_rotate_impl!(Iso3, Vec3);
rand_impl!(Iso3);
approx_eq_impl!(Iso3);
to_homogeneous_impl!(Iso3, Mat4);
inv_impl!(Iso3);
transform_impl!(Iso3, Pnt3);
transformation_impl!(Iso3);
rotate_impl!(Iso3, Vec3);
translation_impl!(Iso3, Vec3);
translate_impl!(Iso3, Pnt3);
iso_mul_iso_impl!(Iso3);
iso_mul_pnt_impl!(Iso3, Pnt3);
pnt_mul_iso_impl!(Iso3, Pnt3);
arbitrary_iso_impl!(Iso3);
// iso_impl!(Iso4, Rot4, Vec4, Vec4);
// rotation_matrix_impl!(Iso4, Rot4, Vec4, Vec4);
// rotation_impl!(Iso4, Rot4, Vec4);
dim_impl!(Iso4, 4);
one_impl!(Iso4);
absolute_rotate_impl!(Iso4, Vec4);
// rand_impl!(Iso4);
approx_eq_impl!(Iso4);
to_homogeneous_impl!(Iso4, Mat5);
inv_impl!(Iso4);
transform_impl!(Iso4, Pnt4);
transformation_impl!(Iso4);
rotate_impl!(Iso4, Vec4);
translation_impl!(Iso4, Vec4);
translate_impl!(Iso4, Pnt4);
iso_mul_iso_impl!(Iso4);
iso_mul_pnt_impl!(Iso4, Pnt4);
pnt_mul_iso_impl!(Iso4, Pnt4);
// FIXME: as soon as Rot4<N>: Arbitrary
// arbitrary_iso_impl!(Iso4);