Rotation is generalized over dimensions
This commit is contained in:
parent
d81157fba5
commit
0c41aa3951
3 changed files with 65 additions and 42 deletions
|
@ -16,6 +16,7 @@
|
||||||
use point::{Point, Point2, Point3};
|
use point::{Point, Point2, Point3};
|
||||||
use vector::{Vector, Vec2, Vec3};
|
use vector::{Vector, Vec2, Vec3};
|
||||||
|
|
||||||
|
/// A generic ray
|
||||||
#[deriving(Clone, Eq)]
|
#[deriving(Clone, Eq)]
|
||||||
pub struct Ray<P,V>
|
pub struct Ray<P,V>
|
||||||
{
|
{
|
||||||
|
|
|
@ -17,49 +17,65 @@ use angle::Rad;
|
||||||
use matrix::Matrix;
|
use matrix::Matrix;
|
||||||
use matrix::{Mat2, ToMat2};
|
use matrix::{Mat2, ToMat2};
|
||||||
use matrix::{Mat3, ToMat3};
|
use matrix::{Mat3, ToMat3};
|
||||||
use point::{Point2, Point3};
|
use point::{Point, Point2, Point3};
|
||||||
use quaternion::{Quat, ToQuat};
|
use quaternion::{Quat, ToQuat};
|
||||||
use ray::{Ray2, Ray3};
|
use ray::{Ray, Ray2, Ray3};
|
||||||
use vector::{Vector, Vec2, Vec3};
|
use vector::{Vector, Vec2, Vec3};
|
||||||
|
|
||||||
|
/// A trait for generic rotation
|
||||||
|
pub trait Rotation
|
||||||
|
<
|
||||||
|
S: Primitive + Clone,
|
||||||
|
Slice,
|
||||||
|
V: Vector<S,Slice>,
|
||||||
|
P: Point<S,V,Slice> + Clone
|
||||||
|
>
|
||||||
|
: Eq
|
||||||
|
+ ApproxEq<S>
|
||||||
|
{
|
||||||
|
fn rotate_point(&self, point: &P) -> P;
|
||||||
|
fn rotate_vec(&self, vec: &V) -> V;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn rotate_ray(&self, ray: &Ray<P,V>) -> Ray<P,V> {
|
||||||
|
Ray::new( ray.origin.clone(), self.rotate_vec(&ray.direction) )
|
||||||
|
}
|
||||||
|
|
||||||
|
fn concat(&self, other: &Self) -> Self;
|
||||||
|
fn invert(&self) -> Self;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn concat_self(&mut self, other: &Self) {
|
||||||
|
*self = self.concat(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn invert_self(&mut self) {
|
||||||
|
*self = self.invert();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A two-dimensional rotation
|
/// A two-dimensional rotation
|
||||||
pub trait Rotation2
|
pub trait Rotation2
|
||||||
<
|
<
|
||||||
S
|
S
|
||||||
>
|
>
|
||||||
: Eq
|
: Rotation<S, [S, ..2], Vec2<S>, Point2<S>>
|
||||||
+ ApproxEq<S>
|
|
||||||
+ ToMat2<S>
|
+ ToMat2<S>
|
||||||
+ ToBasis2<S>
|
+ ToBasis2<S>
|
||||||
{
|
{}
|
||||||
fn rotate_point2(&self, point: &Point2<S>) -> Point2<S>;
|
|
||||||
fn rotate_vec2(&self, vec: &Vec2<S>) -> Vec2<S>;
|
|
||||||
fn rotate_ray2(&self, ray: &Ray2<S>) -> Ray2<S>;
|
|
||||||
fn concat(&self, other: &Self) -> Self;
|
|
||||||
fn concat_self(&mut self, other: &Self);
|
|
||||||
fn invert(&self) -> Self;
|
|
||||||
fn invert_self(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A three-dimensional rotation
|
/// A three-dimensional rotation
|
||||||
pub trait Rotation3
|
pub trait Rotation3
|
||||||
<
|
<
|
||||||
S
|
S
|
||||||
>
|
>
|
||||||
: Eq
|
: Rotation<S, [S, ..3], Vec3<S>, Point3<S>>
|
||||||
+ ApproxEq<S>
|
|
||||||
+ ToMat3<S>
|
+ ToMat3<S>
|
||||||
+ ToBasis3<S>
|
+ ToBasis3<S>
|
||||||
+ ToQuat<S>
|
+ ToQuat<S>
|
||||||
{
|
{}
|
||||||
fn rotate_point3(&self, point: &Point3<S>) -> Point3<S>;
|
|
||||||
fn rotate_vec3(&self, vec: &Vec3<S>) -> Vec3<S>;
|
|
||||||
fn rotate_ray3(&self, ray: &Ray3<S>) -> Ray3<S>;
|
|
||||||
fn concat(&self, other: &Self) -> Self;
|
|
||||||
fn concat_self(&mut self, other: &Self);
|
|
||||||
fn invert(&self) -> Self;
|
|
||||||
fn invert_self(&mut self);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A two-dimensional rotation matrix.
|
/// A two-dimensional rotation matrix.
|
||||||
///
|
///
|
||||||
|
@ -91,15 +107,15 @@ impl<S: Float> ToMat2<S> for Basis2<S> {
|
||||||
fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
|
fn to_mat2(&self) -> Mat2<S> { self.mat.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation2<S> for Basis2<S> {
|
impl<S: Float> Rotation<S, [S, ..2], Vec2<S>, Point2<S>> for Basis2<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_point2(&self, _point: &Point2<S>) -> Point2<S> { fail!("Not yet implemented") }
|
fn rotate_point(&self, _point: &Point2<S>) -> Point2<S> { fail!("Not yet implemented") }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_vec2(&self, vec: &Vec2<S>) -> Vec2<S> { self.mat.mul_v(vec) }
|
fn rotate_vec(&self, vec: &Vec2<S>) -> Vec2<S> { self.mat.mul_v(vec) }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_ray2(&self, _ray: &Ray2<S>) -> Ray2<S> { fail!("Not yet implemented") }
|
fn rotate_ray(&self, _ray: &Ray2<S>) -> Ray2<S> { fail!("Not yet implemented") }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn concat(&self, other: &Basis2<S>) -> Basis2<S> { Basis2 { mat: self.mat.mul_m(&other.mat) } }
|
fn concat(&self, other: &Basis2<S>) -> Basis2<S> { Basis2 { mat: self.mat.mul_m(&other.mat) } }
|
||||||
|
@ -136,6 +152,8 @@ impl<S: Float> ApproxEq<S> for Basis2<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Float> Rotation2<S> for Basis2<S> {}
|
||||||
|
|
||||||
/// A three-dimensional rotation matrix.
|
/// A three-dimensional rotation matrix.
|
||||||
///
|
///
|
||||||
/// The matrix is guaranteed to be orthogonal, so some operations, specifically
|
/// The matrix is guaranteed to be orthogonal, so some operations, specifically
|
||||||
|
@ -207,15 +225,15 @@ impl<S: Float> ToQuat<S> for Basis3<S> {
|
||||||
fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
|
fn to_quat(&self) -> Quat<S> { self.mat.to_quat() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation3<S> for Basis3<S> {
|
impl<S: Float> Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Basis3<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_point3(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }
|
fn rotate_point(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_vec3(&self, vec: &Vec3<S>) -> Vec3<S> { self.mat.mul_v(vec) }
|
fn rotate_vec(&self, vec: &Vec3<S>) -> Vec3<S> { self.mat.mul_v(vec) }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_ray3(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }
|
fn rotate_ray(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn concat(&self, other: &Basis3<S>) -> Basis3<S> { Basis3 { mat: self.mat.mul_m(&other.mat) } }
|
fn concat(&self, other: &Basis3<S>) -> Basis3<S> { Basis3 { mat: self.mat.mul_m(&other.mat) } }
|
||||||
|
@ -252,6 +270,8 @@ impl<S: Float> ApproxEq<S> for Basis3<S> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Float> Rotation3<S> for Basis3<S> {}
|
||||||
|
|
||||||
// Quaternion Rotation impls
|
// Quaternion Rotation impls
|
||||||
|
|
||||||
impl<S: Float> ToBasis3<S> for Quat<S> {
|
impl<S: Float> ToBasis3<S> for Quat<S> {
|
||||||
|
@ -264,15 +284,15 @@ impl<S: Float> ToQuat<S> for Quat<S> {
|
||||||
fn to_quat(&self) -> Quat<S> { self.clone() }
|
fn to_quat(&self) -> Quat<S> { self.clone() }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S: Float> Rotation3<S> for Quat<S> {
|
impl<S: Float> Rotation<S, [S, ..3], Vec3<S>, Point3<S>> for Quat<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_point3(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }
|
fn rotate_point(&self, _point: &Point3<S>) -> Point3<S> { fail!("Not yet implemented") }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_vec3(&self, vec: &Vec3<S>) -> Vec3<S> { self.mul_v(vec) }
|
fn rotate_vec(&self, vec: &Vec3<S>) -> Vec3<S> { self.mul_v(vec) }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn rotate_ray3(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }
|
fn rotate_ray(&self, _ray: &Ray3<S>) -> Ray3<S> { fail!("Not yet implemented") }
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn concat(&self, other: &Quat<S>) -> Quat<S> { self.mul_q(other) }
|
fn concat(&self, other: &Quat<S>) -> Quat<S> { self.mul_q(other) }
|
||||||
|
@ -286,3 +306,5 @@ impl<S: Float> Rotation3<S> for Quat<S> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn invert_self(&mut self) { *self = self.invert() }
|
fn invert_self(&mut self) { *self = self.invert() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<S: Float> Rotation3<S> for Quat<S> {}
|
|
@ -60,11 +60,11 @@ impl<S: Float, R: Rotation3<S>> Transform3<S, R> {
|
||||||
impl <S: Float, R: Rotation3<S>> Transform<S, [S, .. 3], Vec3<S>, Point3<S>> for Transform3<S,R> {
|
impl <S: Float, R: Rotation3<S>> Transform<S, [S, .. 3], Vec3<S>, Point3<S>> for Transform3<S,R> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vec(&self, vec: &Vec3<S>) -> Vec3<S> {
|
fn transform_vec(&self, vec: &Vec3<S>) -> Vec3<S> {
|
||||||
self.rot.rotate_vec3( &vec.mul_s( self.scale.clone() ))
|
self.rot.rotate_vec( &vec.mul_s( self.scale.clone() ))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_point(&self, point: &Point3<S>) -> Point3<S> {
|
fn transform_point(&self, point: &Point3<S>) -> Point3<S> {
|
||||||
self.rot.rotate_point3( &point.mul_s( self.scale.clone() )).add_v( &self.disp )
|
self.rot.rotate_point( &point.mul_s( self.scale.clone() )).add_v( &self.disp )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue