Remove Rotation struct and methods

This commit is contained in:
Brendan Zabarauskas 2012-12-08 12:59:10 +10:00
parent 9669b7bccc
commit b4fbb9c76a
5 changed files with 59 additions and 94 deletions

View file

@ -224,55 +224,6 @@ pub impl<T> Degrees<T>: ToStr {
/**
* An angular rotation around an arbitary axis
*/
pub struct Rotation<T> {
theta: Radians<T>,
axis: Vec3<T>,
}
pub impl<T:Copy Float> Rotation<T> {
#[inline(always)]
static pure fn new(theta: Radians<T>, axis: Vec3<T>) -> Rotation<T> {
Rotation { theta: move theta, axis: move axis }
}
#[inline(always)]
pure fn to_mat3() -> Mat3<T> {
let c: T = cos(&self.theta);
let s: T = sin(&self.theta);
let _0: T = cast(0);
let _1: T = cast(1);
// let _0: T = Number::from(0); // FIXME: causes ICE
// let _1: T = Number::from(1); // FIXME: causes ICE
let _1_c: T = _1 - c;
let x = self.axis.x;
let y = self.axis.y;
let z = self.axis.z;
Mat3::new(_1_c * x * x + c, _1_c * x * y + s * z, _1_c * x * z - s * y,
_1_c * x * y - s * z, _1_c * y * y + c, _1_c * y * z + s * x,
_1_c * x * z + s * y, _1_c * y * z - s * x, _1_c * z * z + c)
}
#[inline(always)]
pure fn to_mat4() -> Mat4<T> {
self.to_mat3().to_mat4()
}
#[inline(always)]
pure fn to_quat() -> Quat<T> {
let half = self.theta / Number::from(2);
Quat::from_sv(cos(&half), self.axis.mul_t(sin(&half)))
}
}
pub struct Euler<T> {
x: Radians<T>, // pitch
y: Radians<T>, // yaw

View file

@ -22,7 +22,7 @@
use core::sys::size_of;
use angle::{Angle, Radians, Degrees, Rotation, Euler};
use angle::{Angle, Radians, Degrees, Euler};
use color::color::{RGB, RGBA, HSV, HSVA};
use mat::{Matrix, Mat2, Mat3, Mat4};
use vec::{Vector, NumericVector, Vec2, Vec3, Vec4};
@ -398,23 +398,6 @@ pub impl ddegrees {
}
// Axis rotation aliases. These are not present in the GLSL specification, but
// they follow roughly the same nomenclature.
pub type rotation = Rotation<f32>; /// a single-precision floating-point axis rotation
pub type drotation = Rotation<f64>; /// a double-precision floating-point axis rotation
pub impl rotation {
#[inline(always)] static pure fn new(theta: radians, axis: vec3) -> rotation { Rotation::new(move theta, move axis) }
#[inline(always)] static pure fn size_of() -> uint { size_of::<rotation>() }
}
pub impl drotation {
#[inline(always)] static pure fn new(theta: dradians, axis: dvec3) -> drotation { Rotation::new(move theta, move axis) }
#[inline(always)] static pure fn size_of() -> uint { size_of::<drotation>() }
}
// Axis rotation aliases. These are not present in the GLSL specification, but
// they follow roughly the same nomenclature.

View file

@ -6,9 +6,11 @@ use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use angle::Angle;
use dim::{Dimensional, ToPtr};
use funs::common::*;
use funs::exponential::*;
use funs::triganomic::{sin, cos};
use num::conv::cast;
use num::kinds::{Float, Number};
use quat::{Quat, ToQuat};
@ -252,6 +254,7 @@ pub trait Matrix2<T,V>: Matrix<T,V> {
* A 3 x 3 matrix
*/
pub trait Matrix3<T,V>: Matrix<T,V> {
static pure fn from_axis_angle<A:Angle<T>>(axis: &Vec3<T>, theta: A) -> Mat3<T>;
pure fn to_mat4(&self) -> Mat4<T>;
}
@ -1043,6 +1046,25 @@ pub impl<T:Copy Float Sign> Mat3<T>: MutableMatrix<T, Vec3<T>> {
}
pub impl<T:Copy Float> Mat3<T>: Matrix3<T, Vec3<T>> {
#[inline(always)]
static pure fn from_axis_angle<A:Angle<T>>(axis: &Vec3<T>, theta: A) -> Mat3<T> {
let c: T = cos(&theta.to_radians());
let s: T = sin(&theta.to_radians());
let _0: T = cast(0);
let _1: T = cast(1);
// let _0: T = Number::from(0); // FIXME: causes ICE
// let _1: T = Number::from(1); // FIXME: causes ICE
let _1_c: T = _1 - c;
let x = axis.x;
let y = axis.y;
let z = axis.z;
Mat3::new(_1_c * x * x + c, _1_c * x * y + s * z, _1_c * x * z - s * y,
_1_c * x * y - s * z, _1_c * y * y + c, _1_c * y * z + s * x,
_1_c * x * z + s * y, _1_c * y * z - s * x, _1_c * z * z + c)
}
#[inline(always)]
pure fn to_mat4(&self) -> Mat4<T> {
Mat4::from_Mat3(self)

View file

@ -15,6 +15,7 @@ use core::vec::raw::buf_as_slice;
use std::cmp::FuzzyEq;
use angle::Angle;
use dim::{Dimensional, ToPtr};
use funs::common::*;
use funs::exponential::*;
@ -34,6 +35,8 @@ use vec::Vec3;
* components of the quaternion.
*/
pub trait Quaternion<T,V3>: Dimensional<T>, ToPtr<T>, Eq, Neg<self> {
static pure fn from_axis_angle<A:Angle<T>>(axis: &Vec3<T>, theta: A) -> self;
/**
* # Return value
*
@ -258,6 +261,12 @@ pub impl<T:Copy> Quat<T>: ToPtr<T> {
}
pub impl<T:Copy Float Exp Extent InvTrig> Quat<T>: Quaternion<T, Vec3<T>> {
#[inline(always)]
static pure fn from_axis_angle<A:Angle<T>>(axis: &Vec3<T>, theta: A) -> Quat<T> {
let half = theta.to_radians() / Number::from(2);
Quat::from_sv(cos(&half), axis.mul_t(sin(&half)))
}
#[inline(always)]
static pure fn identity() -> Quat<T> {
Quat::new(Number::from(1),

View file

@ -80,40 +80,40 @@ fn test_degrees() {
#[test]
fn test_rotation() {
{
let pos = Vec4::new(1.0, 0.0, 0.0, 1.0); // the position to transform
let rot = Rotation {
theta: Degrees(180.0).to_radians(),
axis: Vec3::new(0.0, 0.0, 1.0), // unit_z
};
// {
// let pos = Vec4::new(1.0, 0.0, 0.0, 1.0); // the position to transform
// let rot = Rotation {
// theta: Degrees(180.0).to_radians(),
// axis: Vec3::new(0.0, 0.0, 1.0), // unit_z
// };
let newpos = rot.to_mat4().mul_v(&pos);
let expected_pos = Vec4::new(-1.0, 0.0, 0.0, 1.0);
// let newpos = rot.to_mat4().mul_v(&pos);
// let expected_pos = Vec4::new(-1.0, 0.0, 0.0, 1.0);
assert newpos.fuzzy_eq(&expected_pos);
}
{
let pos = Vec4::new(4f32, 0f32, 0f32, 1f32);
// assert newpos.fuzzy_eq(&expected_pos);
// }
// {
// let pos = Vec4::new(4f32, 0f32, 0f32, 1f32);
let rot_a = Rotation {
theta: Degrees(90f32).to_radians(),
axis: Vec3::new(0f32, 1f32, 0f32), // unit_y
};
// let rot_a = Rotation {
// theta: Degrees(90f32).to_radians(),
// axis: Vec3::new(0f32, 1f32, 0f32), // unit_y
// };
let rot_b = Rotation {
theta: Degrees(90f32).to_radians(),
axis: -Vec3::new(0f32, 1f32, 0f32), // -unit_y
};
// let rot_b = Rotation {
// theta: Degrees(90f32).to_radians(),
// axis: -Vec3::new(0f32, 1f32, 0f32), // -unit_y
// };
let newpos_a = rot_a.to_mat4().mul_v(&pos);
let newpos_b = rot_b.to_mat4().mul_v(&pos);
// let newpos_a = rot_a.to_mat4().mul_v(&pos);
// let newpos_b = rot_b.to_mat4().mul_v(&pos);
let expected_pos_a = Vec4::new(0f32, 0f32, -4f32, 1f32);
let expected_pos_b = Vec4::new(0f32, 0f32, 4f32, 1f32);
// let expected_pos_a = Vec4::new(0f32, 0f32, -4f32, 1f32);
// let expected_pos_b = Vec4::new(0f32, 0f32, 4f32, 1f32);
assert newpos_a.fuzzy_eq(&expected_pos_a);
assert newpos_b.fuzzy_eq(&expected_pos_b);
}
// assert newpos_a.fuzzy_eq(&expected_pos_a);
// assert newpos_b.fuzzy_eq(&expected_pos_b);
// }
// TODO: test to_quat
}