forked from M-Labs/nalgebra
Add utility methods.
Added look_at for 3d rotation matrix and 3d transform. Rotation matrices constructors are now the static methods Rotmat::from_angle, Rotmat::from_axis_angle.
This commit is contained in:
parent
0577f3e364
commit
81389a911a
@ -3,6 +3,7 @@ use std::rand::{Rand, Rng, RngUtil};
|
|||||||
use std::cmp::ApproxEq;
|
use std::cmp::ApproxEq;
|
||||||
use traits::division_ring::DivisionRing;
|
use traits::division_ring::DivisionRing;
|
||||||
use traits::rlmul::{RMul, LMul};
|
use traits::rlmul::{RMul, LMul};
|
||||||
|
use traits::cross::Cross;
|
||||||
use traits::dim::Dim;
|
use traits::dim::Dim;
|
||||||
use traits::inv::Inv;
|
use traits::inv::Inv;
|
||||||
use traits::transpose::Transpose;
|
use traits::transpose::Transpose;
|
||||||
@ -25,50 +26,68 @@ impl<M: Clone> Rotmat<M>
|
|||||||
{ self.submat.clone() }
|
{ self.submat.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotmat2<N: Clone + Trigonometric + Neg<N>>(angle: N) -> Rotmat<Mat2<N>>
|
impl<N: Clone + Trigonometric + Neg<N>> Rotmat<Mat2<N>>
|
||||||
{
|
{
|
||||||
let (sia, coa) = angle.sin_cos();
|
pub fn from_angle(angle: N) -> Rotmat<Mat2<N>>
|
||||||
|
{
|
||||||
|
let (sia, coa) = angle.sin_cos();
|
||||||
|
|
||||||
Rotmat
|
Rotmat { submat: Mat2::new(coa.clone(), -sia, sia.clone(), coa) }
|
||||||
{ submat: Mat2::new(coa.clone(), -sia, sia.clone(), coa) }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rotmat3<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
impl<N: Clone + Trigonometric + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
||||||
(axisangle: Vec3<N>) -> Rotmat<Mat3<N>>
|
|
||||||
{
|
{
|
||||||
if axisangle.sqnorm().is_zero()
|
pub fn from_axis_angle(axisangle: Vec3<N>) -> Rotmat<Mat3<N>>
|
||||||
{ One::one() }
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
let mut axis = axisangle;
|
if axisangle.sqnorm().is_zero()
|
||||||
let angle = axis.normalize();
|
{ One::one() }
|
||||||
let _1 = One::one::<N>();
|
else
|
||||||
let ux = axis.x.clone();
|
{
|
||||||
let uy = axis.y.clone();
|
let mut axis = axisangle;
|
||||||
let uz = axis.z.clone();
|
let angle = axis.normalize();
|
||||||
let sqx = ux * ux;
|
let _1 = One::one::<N>();
|
||||||
let sqy = uy * uy;
|
let ux = axis.x.clone();
|
||||||
let sqz = uz * uz;
|
let uy = axis.y.clone();
|
||||||
let (sin, cos) = angle.sin_cos();
|
let uz = axis.z.clone();
|
||||||
let one_m_cos = _1 - cos;
|
let sqx = ux * ux;
|
||||||
|
let sqy = uy * uy;
|
||||||
|
let sqz = uz * uz;
|
||||||
|
let (sin, cos) = angle.sin_cos();
|
||||||
|
let one_m_cos = _1 - cos;
|
||||||
|
|
||||||
Rotmat {
|
Rotmat {
|
||||||
submat: Mat3::new(
|
submat: Mat3::new(
|
||||||
(sqx + (_1 - sqx) * cos),
|
(sqx + (_1 - sqx) * cos),
|
||||||
(ux * uy * one_m_cos - uz * sin),
|
(ux * uy * one_m_cos - uz * sin),
|
||||||
(ux * uz * one_m_cos + uy * sin),
|
(ux * uz * one_m_cos + uy * sin),
|
||||||
|
|
||||||
(ux * uy * one_m_cos + uz * sin),
|
(ux * uy * one_m_cos + uz * sin),
|
||||||
(sqy + (_1 - sqy) * cos),
|
(sqy + (_1 - sqy) * cos),
|
||||||
(uy * uz * one_m_cos - ux * sin),
|
(uy * uz * one_m_cos - ux * sin),
|
||||||
|
|
||||||
(ux * uz * one_m_cos - uy * sin),
|
(ux * uz * one_m_cos - uy * sin),
|
||||||
(uy * uz * one_m_cos + ux * sin),
|
(uy * uz * one_m_cos + ux * sin),
|
||||||
(sqz + (_1 - sqz) * cos))
|
(sqz + (_1 - sqz) * cos))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<N: Clone + DivisionRing + Algebraic> Rotmat<Mat3<N>>
|
||||||
|
{
|
||||||
|
pub fn look_at(&mut self, at: &Vec3<N>, up: &Vec3<N>)
|
||||||
|
{
|
||||||
|
let zaxis = at.normalized();
|
||||||
|
let xaxis = up.cross(&zaxis).normalized();
|
||||||
|
let yaxis = zaxis.cross(&xaxis);
|
||||||
|
|
||||||
|
self.submat = Mat3::new(xaxis.x.clone(), yaxis.x.clone(), zaxis.x.clone(),
|
||||||
|
xaxis.y.clone(), yaxis.y.clone(), zaxis.y.clone(),
|
||||||
|
xaxis.z , yaxis.z , zaxis.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<N: Trigonometric + DivisionRing + Clone>
|
impl<N: Trigonometric + DivisionRing + Clone>
|
||||||
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
|
Rotation<Vec1<N>> for Rotmat<Mat2<N>>
|
||||||
{
|
{
|
||||||
@ -90,7 +109,7 @@ Rotatable<Vec1<N>, Rotmat<Mat2<N>>> for Rotmat<Mat2<N>>
|
|||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
|
fn rotated(&self, rot: &Vec1<N>) -> Rotmat<Mat2<N>>
|
||||||
{ rotmat2(rot.x.clone()) * *self }
|
{ Rotmat::from_angle(rot.x.clone()) * *self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
impl<N: Clone + Trigonometric + DivisionRing + Algebraic>
|
||||||
@ -115,14 +134,14 @@ Rotatable<Vec3<N>, Rotmat<Mat3<N>>> for Rotmat<Mat3<N>>
|
|||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>>
|
fn rotated(&self, axisangle: &Vec3<N>) -> Rotmat<Mat3<N>>
|
||||||
{ rotmat3(axisangle.clone()) * *self }
|
{ Rotmat::from_axis_angle(axisangle.clone()) * *self }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
|
impl<N: Clone + Rand + Trigonometric + Neg<N>> Rand for Rotmat<Mat2<N>>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>>
|
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat2<N>>
|
||||||
{ rotmat2(rng.gen()) }
|
{ Rotmat::from_angle(rng.gen()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M>
|
impl<M: RMul<V> + LMul<V>, V> Rotate<V> for Rotmat<M>
|
||||||
@ -152,7 +171,7 @@ Rand for Rotmat<Mat3<N>>
|
|||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>>
|
fn rand<R: Rng>(rng: &mut R) -> Rotmat<Mat3<N>>
|
||||||
{ rotmat3(rng.gen()) }
|
{ Rotmat::from_axis_angle(rng.gen()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: Dim> Dim for Rotmat<M>
|
impl<M: Dim> Dim for Rotmat<M>
|
||||||
|
@ -3,6 +3,7 @@ use std::rand::{Rand, Rng, RngUtil};
|
|||||||
use std::cmp::ApproxEq;
|
use std::cmp::ApproxEq;
|
||||||
use traits::dim::Dim;
|
use traits::dim::Dim;
|
||||||
use traits::inv::Inv;
|
use traits::inv::Inv;
|
||||||
|
use traits::division_ring::DivisionRing;
|
||||||
use traits::rotation::{Rotation, Rotate, Rotatable};
|
use traits::rotation::{Rotation, Rotate, Rotatable};
|
||||||
use traits::translation::{Translation, Translate, Translatable};
|
use traits::translation::{Translation, Translate, Translatable};
|
||||||
use Ts = traits::transformation::Transform;
|
use Ts = traits::transformation::Transform;
|
||||||
@ -10,6 +11,9 @@ use traits::transformation::{Transformation, Transformable};
|
|||||||
use traits::rlmul::{RMul, LMul};
|
use traits::rlmul::{RMul, LMul};
|
||||||
use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
|
use traits::homogeneous::{ToHomogeneous, FromHomogeneous};
|
||||||
use traits::column::Column;
|
use traits::column::Column;
|
||||||
|
use adaptors::rotmat::Rotmat;
|
||||||
|
use vec::Vec3;
|
||||||
|
use mat::Mat3;
|
||||||
|
|
||||||
#[deriving(Eq, ToStr, Clone)]
|
#[deriving(Eq, ToStr, Clone)]
|
||||||
pub struct Transform<M, V>
|
pub struct Transform<M, V>
|
||||||
@ -36,7 +40,16 @@ impl<M: Clone, V: Clone> Transform<M, V>
|
|||||||
{ self.subtrans.clone() }
|
{ self.subtrans.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M:Dim, V> Dim for Transform<M, V>
|
impl<N: Clone + DivisionRing + Algebraic> Transform<Rotmat<Mat3<N>>, Vec3<N>>
|
||||||
|
{
|
||||||
|
pub fn look_at(&mut self, eye: &Vec3<N>, at: &Vec3<N>, up: &Vec3<N>)
|
||||||
|
{
|
||||||
|
self.submat.look_at(&(*at - *eye), up);
|
||||||
|
self.subtrans = self.submat.rotate(&-eye);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M: Dim, V> Dim for Transform<M, V>
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn dim() -> uint
|
fn dim() -> uint
|
||||||
|
Loading…
Reference in New Issue
Block a user