2013-10-06 22:54:09 +08:00
|
|
|
//! Isometric transformations.
|
|
|
|
|
2014-11-01 00:40:47 +08:00
|
|
|
#![allow(missing_docs)]
|
2013-10-06 22:54:09 +08:00
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
use std::rand::{Rand, Rng};
|
2013-11-22 16:46:48 +08:00
|
|
|
use structs::mat::{Mat3, Mat4, Mat5};
|
2014-11-16 21:04:15 +08:00
|
|
|
use traits::structure::{Cast, Dim, Col, BaseFloat, BaseNum, One};
|
|
|
|
use traits::operations::{Inv, ApproxEq};
|
2013-10-06 22:54:09 +08:00
|
|
|
use traits::geometry::{RotationMatrix, Rotation, Rotate, AbsoluteRotate, Transform, Transformation,
|
|
|
|
Translate, Translation, ToHomogeneous};
|
|
|
|
|
2014-10-11 04:16:47 +08:00
|
|
|
use structs::vec::{Vec1, Vec2, Vec3, Vec4};
|
2014-11-26 21:17:34 +08:00
|
|
|
use structs::pnt::{Pnt2, Pnt3, Pnt4};
|
2013-10-06 22:54:09 +08:00
|
|
|
use structs::rot::{Rot2, Rot3, Rot4};
|
|
|
|
|
|
|
|
|
|
|
|
/// 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.
|
2014-12-10 22:37:49 +08:00
|
|
|
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Show, Copy)]
|
2013-10-06 22:54:09 +08:00
|
|
|
pub struct Iso2<N> {
|
|
|
|
/// The rotation applicable by this isometry.
|
2014-04-04 02:52:52 +08:00
|
|
|
pub rotation: Rot2<N>,
|
2013-10-06 22:54:09 +08:00
|
|
|
/// The translation applicable by this isometry.
|
2014-04-04 02:52:52 +08:00
|
|
|
pub translation: Vec2<N>
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2014-12-10 22:37:49 +08:00
|
|
|
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Show, Copy)]
|
2013-10-06 22:54:09 +08:00
|
|
|
pub struct Iso3<N> {
|
|
|
|
/// The rotation applicable by this isometry.
|
2014-04-04 02:52:52 +08:00
|
|
|
pub rotation: Rot3<N>,
|
2013-10-06 22:54:09 +08:00
|
|
|
/// The translation applicable by this isometry.
|
2014-04-04 02:52:52 +08:00
|
|
|
pub translation: Vec3<N>
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Four dimensional isometry.
|
|
|
|
///
|
|
|
|
/// Isometries conserve angles and distances, hence do not allow shearing nor scaling.
|
2014-12-10 22:37:49 +08:00
|
|
|
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Show, Copy)]
|
2013-10-06 22:54:09 +08:00
|
|
|
pub struct Iso4<N> {
|
|
|
|
/// The rotation applicable by this isometry.
|
2014-04-04 02:52:52 +08:00
|
|
|
pub rotation: Rot4<N>,
|
2013-10-06 22:54:09 +08:00
|
|
|
/// The translation applicable by this isometry.
|
2014-04-04 02:52:52 +08:00
|
|
|
pub translation: Vec4<N>
|
2013-10-06 22:54:09 +08:00
|
|
|
}
|
|
|
|
|
2014-11-15 22:47:59 +08:00
|
|
|
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.
|
2014-10-11 02:56:24 +08:00
|
|
|
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);
|
2014-10-11 02:56:24 +08:00
|
|
|
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.
|
2014-10-11 02:56:24 +08:00
|
|
|
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);
|
2014-10-11 02:56:24 +08:00
|
|
|
self.translation = eye.as_vec().clone();
|
2013-10-09 03:00:25 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-22 16:46:48 +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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-14 17:22:38 +08:00
|
|
|
iso_impl!(Iso2, Rot2, Vec2, Vec1)
|
2013-10-06 22:54:09 +08:00
|
|
|
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)
|
2014-11-26 21:17:34 +08:00
|
|
|
transform_impl!(Iso2, Pnt2)
|
2013-10-06 22:54:09 +08:00
|
|
|
transformation_impl!(Iso2)
|
|
|
|
rotate_impl!(Iso2, Vec2)
|
|
|
|
translation_impl!(Iso2, Vec2)
|
2014-10-10 17:23:52 +08:00
|
|
|
translate_impl!(Iso2, Pnt2)
|
2014-11-26 21:17:34 +08:00
|
|
|
iso_mul_iso_impl!(Iso2)
|
|
|
|
iso_mul_pnt_impl!(Iso2, Pnt2)
|
|
|
|
pnt_mul_iso_impl!(Iso2, Pnt2)
|
2013-10-06 22:54:09 +08:00
|
|
|
|
2013-10-14 17:22:38 +08:00
|
|
|
iso_impl!(Iso3, Rot3, Vec3, Vec3)
|
2013-10-06 22:54:09 +08:00
|
|
|
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)
|
2014-11-26 21:17:34 +08:00
|
|
|
transform_impl!(Iso3, Pnt3)
|
2013-10-06 22:54:09 +08:00
|
|
|
transformation_impl!(Iso3)
|
|
|
|
rotate_impl!(Iso3, Vec3)
|
|
|
|
translation_impl!(Iso3, Vec3)
|
2014-10-10 17:23:52 +08:00
|
|
|
translate_impl!(Iso3, Pnt3)
|
2014-11-26 21:17:34 +08:00
|
|
|
iso_mul_iso_impl!(Iso3)
|
|
|
|
iso_mul_pnt_impl!(Iso3, Pnt3)
|
|
|
|
pnt_mul_iso_impl!(Iso3, Pnt3)
|
2013-10-06 22:54:09 +08:00
|
|
|
|
2013-11-22 16:46:48 +08:00
|
|
|
// iso_impl!(Iso4, Rot4, Vec4, Vec4)
|
2013-10-06 22:54:09 +08:00
|
|
|
// rotation_matrix_impl!(Iso4, Rot4, Vec4, Vec4)
|
|
|
|
// rotation_impl!(Iso4, Rot4, Vec4)
|
|
|
|
dim_impl!(Iso4, 4)
|
|
|
|
one_impl!(Iso4)
|
2013-11-22 16:46:48 +08:00
|
|
|
absolute_rotate_impl!(Iso4, Vec4)
|
2013-10-06 22:54:09 +08:00
|
|
|
// rand_impl!(Iso4)
|
|
|
|
approx_eq_impl!(Iso4)
|
|
|
|
to_homogeneous_impl!(Iso4, Mat5)
|
|
|
|
inv_impl!(Iso4)
|
2014-11-26 21:17:34 +08:00
|
|
|
transform_impl!(Iso4, Pnt4)
|
2013-10-06 22:54:09 +08:00
|
|
|
transformation_impl!(Iso4)
|
2013-11-22 16:46:48 +08:00
|
|
|
rotate_impl!(Iso4, Vec4)
|
2013-10-06 22:54:09 +08:00
|
|
|
translation_impl!(Iso4, Vec4)
|
2014-10-10 17:23:52 +08:00
|
|
|
translate_impl!(Iso4, Pnt4)
|
2014-11-26 21:17:34 +08:00
|
|
|
iso_mul_iso_impl!(Iso4)
|
|
|
|
iso_mul_pnt_impl!(Iso4, Pnt4)
|
|
|
|
pnt_mul_iso_impl!(Iso4, Pnt4)
|