Move axial rotation conversions to angle module
This commit is contained in:
parent
11b5b12d0a
commit
c3071b6260
6 changed files with 80 additions and 65 deletions
40
src/angle.rs
40
src/angle.rs
|
@ -1,8 +1,14 @@
|
|||
use core::cmp::{Eq, Ord};
|
||||
use core::f64::consts::pi;
|
||||
use num::cast::*;
|
||||
use funs::triganomic::{cos, sin};
|
||||
use mat::{Mat3, Mat4};
|
||||
use num::cast::{NumCast, cast};
|
||||
use quat::Quat;
|
||||
use vec::Vec3;
|
||||
|
||||
/**
|
||||
* The base trait for anglular units
|
||||
*/
|
||||
pub trait Angle<T>: Add<self,self>
|
||||
, Sub<self,self>
|
||||
, Mul<T,self>
|
||||
|
@ -66,11 +72,41 @@ pub impl<T:Copy Ord> Degrees<T>: Ord {
|
|||
#[inline(always)] pure fn gt(other: &Degrees<T>) -> bool { *self > **other }
|
||||
}
|
||||
|
||||
pub struct AxialRotation<T> {
|
||||
/**
|
||||
* An angular rotation around an arbitary axis
|
||||
*/
|
||||
pub struct Rotation<T> {
|
||||
axis: Vec3<T>,
|
||||
theta: Radians<T>,
|
||||
}
|
||||
|
||||
pub impl<T:Copy Num NumCast> Rotation<T> {
|
||||
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 t: T = _1 - c;
|
||||
|
||||
let x = self.axis.x;
|
||||
let y = self.axis.y;
|
||||
let z = self.axis.z;
|
||||
|
||||
Mat3::new(t * x * x + c, t * x * y + s * z, t * x * z - s * y,
|
||||
t * x * y - s * z, t * y * y + c, t * y * z + s * x,
|
||||
t * x * z - s - y, t * y * z - s * x, t * z * z + c)
|
||||
}
|
||||
|
||||
pure fn to_mat4() -> Mat4<T> {
|
||||
self.to_mat3().to_mat4()
|
||||
}
|
||||
|
||||
pure fn to_quat() -> Quat<T> {
|
||||
let half = self.theta / cast(2);
|
||||
Quat::from_sv(cos(&half), self.axis.mul_t(sin(&half)))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Euler<T> {
|
||||
x: Radians<T>, // pitch
|
||||
y: Radians<T>, // yaw
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
use funs::transform::*;
|
||||
use angle::Degrees;
|
||||
use mat::Mat4;
|
||||
use vec::{Vec3, Vec4};
|
||||
|
||||
#[test]
|
||||
fn test_mat4_from_rotation() {
|
||||
{
|
||||
let pos = Vec4::new(1f32, 0f32, 0f32, 1f32);
|
||||
// let tform = mat4_from_rotation(180f32, Vec3::unit_z());
|
||||
let tform = mat4_from_rotation(Degrees(180f32).to_radians(), Vec3::new(0f32, 0f32, 1f32));
|
||||
let newpos = tform.mul_v(&pos);
|
||||
|
||||
let expected = Vec4::new(-1f32, 0f32, 0f32, 1f32);
|
||||
|
||||
assert newpos == expected;
|
||||
}
|
||||
{
|
||||
let pos = Vec4::new(4f32, 0f32, 0f32, 1f32);
|
||||
|
||||
// let tform_a = mat4_from_rotation(90f32, Vec3::unit_y());
|
||||
// let tform_b = mat4_from_rotation(90f32, -Vec3::unit_y());
|
||||
let tform_a = mat4_from_rotation(Degrees(90f32).to_radians(), Vec3::new(0f32, 1f32, 0f32));
|
||||
let tform_b = mat4_from_rotation(Degrees(90f32).to_radians(), -Vec3::new(0f32, 1f32, 0f32));
|
||||
let newpos_a = tform_a.mul_v(&pos);
|
||||
let newpos_b = tform_b.mul_v(&pos);
|
||||
|
||||
let expected_a = Vec4::new(0f32, 0f32, -4f32, 1f32);
|
||||
let expected_b = Vec4::new(0f32, 0f32, 4f32, 1f32);
|
||||
|
||||
assert newpos_a == expected_a;
|
||||
assert newpos_b == expected_b;
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
use funs::triganomic::{cos, sin};
|
||||
use angle::Radians;
|
||||
use mat::{Mat3, Mat4};
|
||||
use num::cast::{NumCast, cast};
|
||||
use vec::Vec3;
|
||||
|
||||
pub pure fn mat3_from_rotation<T:Copy Num NumCast>(theta: Radians<T>, axis: Vec3<T>) -> Mat3<T> {
|
||||
let c: T = cos(&theta);
|
||||
let s: T = sin(&theta);
|
||||
let _0: T = cast(0);
|
||||
let _1: T = cast(1);
|
||||
let t: T = _1 - c;
|
||||
|
||||
Mat3::new(t * axis.x * axis.x + c, t * axis.x * axis.y + s * axis.z, t * axis.x * axis.z - s * axis.y,
|
||||
t * axis.x * axis.y - s * axis.z, t * axis.y * axis.y + c, t * axis.y * axis.z + s * axis.x,
|
||||
t * axis.x * axis.z - s - axis.y, t * axis.y * axis.z - s * axis.x, t * axis.z * axis.z + c)
|
||||
}
|
||||
|
||||
pub pure fn mat4_from_rotation<T:Copy Num NumCast>(theta: Radians<T>, axis: Vec3<T>) -> Mat4<T> {
|
||||
mat3_from_rotation(theta, axis).to_mat4()
|
||||
}
|
|
@ -39,13 +39,11 @@ pub mod funs {
|
|||
pub mod exponential;
|
||||
pub mod projection;
|
||||
pub mod relational;
|
||||
pub mod transform;
|
||||
pub mod triganomic;
|
||||
|
||||
#[test]
|
||||
mod test {
|
||||
mod test_common;
|
||||
mod test_relational;
|
||||
mod test_transform;
|
||||
}
|
||||
}
|
|
@ -220,12 +220,6 @@ pub impl<T:Copy Num NumCast Exp Clamp Ord InvTrig> Quat<T>: Quaternion<T> {
|
|||
|
||||
self.mul_t(cos(&theta)).add_q(&q.mul_t(sin(&theta)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub pure fn from_axis_angle(axis: Vec3<T>, theta: Radians<T>) -> Quat<T> {
|
||||
let half = theta / cast(2);
|
||||
Quat::from_sv(cos(&half), axis.mul_t(sin(&half)))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pure fn to_mat3() -> Mat3<T> {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
use core::float::consts::pi;
|
||||
|
||||
use angle::*;
|
||||
use mat::Mat4;
|
||||
use vec::{Vec3, Vec4};
|
||||
|
||||
#[test]
|
||||
fn test_radians() {
|
||||
|
@ -44,4 +46,44 @@ fn test_degrees() {
|
|||
assert *(Degrees(180.0) / 2.0) == *Degrees(90.0);
|
||||
assert *(Degrees(540.0) % (360.0)) == *Degrees(180.0);
|
||||
assert *(-Degrees(180.0)) == *Degrees(-180.0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_rotation() {
|
||||
{
|
||||
let pos = Vec4::new(1.0, 0.0, 0.0, 1.0); // the position to transform
|
||||
let rot = Rotation {
|
||||
axis: Vec3::new(0.0, 0.0, 1.0), // unit_z
|
||||
theta: Degrees(180.0).to_radians(),
|
||||
};
|
||||
|
||||
let newpos = rot.to_mat4().mul_v(&pos);
|
||||
let expected_pos = Vec4::new(-1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
assert newpos == expected_pos;
|
||||
}
|
||||
{
|
||||
let pos = Vec4::new(4f32, 0f32, 0f32, 1f32);
|
||||
|
||||
let rot_a = Rotation {
|
||||
axis: Vec3::new(0f32, 1f32, 0f32), // unit_y
|
||||
theta: Degrees(90f32).to_radians(),
|
||||
};
|
||||
|
||||
let rot_b = Rotation {
|
||||
axis: -Vec3::new(0f32, 1f32, 0f32), // -unit_y
|
||||
theta: Degrees(90f32).to_radians(),
|
||||
};
|
||||
|
||||
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);
|
||||
|
||||
assert newpos_a == expected_pos_a;
|
||||
assert newpos_b == expected_pos_b;
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue