2013-10-06 22:54:09 +08:00
|
|
|
//! Isometric transformations.
|
|
|
|
|
2014-04-02 04:58:06 +08:00
|
|
|
#![allow(missing_doc)]
|
2013-10-06 22:54:09 +08:00
|
|
|
|
|
|
|
use std::num::{Zero, One};
|
2014-03-14 05:44:14 +08:00
|
|
|
use rand::{Rand, Rng};
|
2013-11-22 16:46:48 +08:00
|
|
|
use structs::mat::{Mat3, Mat4, Mat5};
|
2013-10-10 04:59:44 +08:00
|
|
|
use traits::structure::{Cast, Dim, Col};
|
2014-01-10 03:48:30 +08:00
|
|
|
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};
|
|
|
|
|
2013-11-22 16:46:48 +08:00
|
|
|
use structs::vec::{Vec1, Vec2, Vec3, Vec4, Vec2MulRhs, Vec3MulRhs, Vec4MulRhs};
|
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-06-04 04:37:46 +08:00
|
|
|
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Show)]
|
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-06-04 04:37:46 +08:00
|
|
|
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Show)]
|
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-06-04 04:37:46 +08:00
|
|
|
#[deriving(Eq, PartialEq, Encodable, Decodable, Clone, Show)]
|
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-05-17 03:04:35 +08:00
|
|
|
impl<N: Clone + Float> 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: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) {
|
|
|
|
self.rotation.look_at(&(*at - *eye), up);
|
|
|
|
self.translation = eye.clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>) {
|
|
|
|
self.rotation.look_at_z(&(*at - *eye), up);
|
|
|
|
self.translation = eye.clone();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
|
|
double_dispatch_binop_decl_trait!(Iso2, Iso2MulRhs)
|
|
|
|
mul_redispatch_impl!(Iso2, Iso2MulRhs)
|
|
|
|
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, Vec2)
|
|
|
|
transformation_impl!(Iso2)
|
|
|
|
rotate_impl!(Iso2, Vec2)
|
|
|
|
translation_impl!(Iso2, Vec2)
|
|
|
|
translate_impl!(Iso2, Vec2)
|
|
|
|
iso_mul_iso_impl!(Iso2, Iso2MulRhs)
|
|
|
|
iso_mul_vec_impl!(Iso2, Vec2, Iso2MulRhs)
|
|
|
|
vec_mul_iso_impl!(Iso2, Vec2, Vec2MulRhs)
|
|
|
|
|
2013-10-14 17:22:38 +08:00
|
|
|
iso_impl!(Iso3, Rot3, Vec3, Vec3)
|
2013-10-06 22:54:09 +08:00
|
|
|
double_dispatch_binop_decl_trait!(Iso3, Iso3MulRhs)
|
|
|
|
mul_redispatch_impl!(Iso3, Iso3MulRhs)
|
|
|
|
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, Vec3)
|
|
|
|
transformation_impl!(Iso3)
|
|
|
|
rotate_impl!(Iso3, Vec3)
|
|
|
|
translation_impl!(Iso3, Vec3)
|
|
|
|
translate_impl!(Iso3, Vec3)
|
|
|
|
iso_mul_iso_impl!(Iso3, Iso3MulRhs)
|
|
|
|
iso_mul_vec_impl!(Iso3, Vec3, Iso3MulRhs)
|
|
|
|
vec_mul_iso_impl!(Iso3, Vec3, Vec3MulRhs)
|
|
|
|
|
2013-11-22 16:46:48 +08:00
|
|
|
// iso_impl!(Iso4, Rot4, Vec4, Vec4)
|
2013-10-06 22:54:09 +08:00
|
|
|
double_dispatch_binop_decl_trait!(Iso4, Iso4MulRhs)
|
|
|
|
mul_redispatch_impl!(Iso4, Iso4MulRhs)
|
|
|
|
// 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)
|
|
|
|
transform_impl!(Iso4, Vec4)
|
|
|
|
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)
|
|
|
|
translate_impl!(Iso4, Vec4)
|
|
|
|
iso_mul_iso_impl!(Iso4, Iso4MulRhs)
|
|
|
|
iso_mul_vec_impl!(Iso4, Vec4, Iso4MulRhs)
|
|
|
|
vec_mul_iso_impl!(Iso4, Vec4, Vec4MulRhs)
|