2015-03-26 05:36:19 +08:00
|
|
|
extern crate nalgebra as na;
|
2015-02-17 20:32:54 +08:00
|
|
|
extern crate rand;
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-07-30 00:02:37 +08:00
|
|
|
use na::{Point3, Quaternion, Vector3, Rotation3, UnitQuaternion, Rotation, one};
|
2015-02-17 20:32:54 +08:00
|
|
|
use rand::random;
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
|
|
#[test]
|
2016-04-17 23:26:58 +08:00
|
|
|
fn test_quaternion_as_matrix() {
|
2016-01-10 21:49:55 +08:00
|
|
|
for _ in 0usize .. 10000 {
|
2016-04-17 23:26:58 +08:00
|
|
|
let axis_angle: Vector3<f64> = random();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-08-16 16:48:41 +08:00
|
|
|
assert!(na::approx_eq(&UnitQuaternion::from_scaled_axis(axis_angle).to_rotation_matrix(), &Rotation3::new(axis_angle)))
|
2014-10-15 03:37:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-04-17 23:26:58 +08:00
|
|
|
fn test_quaternion_mul_vec_or_point_as_matrix() {
|
2016-01-10 21:49:55 +08:00
|
|
|
for _ in 0usize .. 10000 {
|
2016-04-17 23:26:58 +08:00
|
|
|
let axis_angle: Vector3<f64> = random();
|
2016-08-16 18:26:36 +08:00
|
|
|
let vector: Vector3<f64> = random();
|
|
|
|
let point: Point3<f64> = random();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-08-16 18:26:36 +08:00
|
|
|
let matrix = Rotation3::new(axis_angle);
|
2016-08-16 16:48:41 +08:00
|
|
|
let quaternion = UnitQuaternion::from_scaled_axis(axis_angle);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-04-17 23:26:58 +08:00
|
|
|
assert!(na::approx_eq(&(matrix * vector), &(quaternion * vector)));
|
2016-08-16 18:26:36 +08:00
|
|
|
assert!(na::approx_eq(&(matrix * point), &(quaternion * point)));
|
2016-04-17 23:26:58 +08:00
|
|
|
assert!(na::approx_eq(&(vector * matrix), &(vector * quaternion)));
|
2016-08-16 18:26:36 +08:00
|
|
|
assert!(na::approx_eq(&(point * matrix), &(point * quaternion)));
|
2014-10-15 03:37:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-04-17 23:26:58 +08:00
|
|
|
fn test_quaternion_div_quaternion() {
|
2016-01-10 21:49:55 +08:00
|
|
|
for _ in 0usize .. 10000 {
|
2016-04-17 23:26:58 +08:00
|
|
|
let axis_angle1: Vector3<f64> = random();
|
|
|
|
let axis_angle2: Vector3<f64> = random();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-04-17 23:26:58 +08:00
|
|
|
let r1 = Rotation3::new(axis_angle1);
|
|
|
|
let r2 = na::inverse(&Rotation3::new(axis_angle2)).unwrap();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-08-16 16:48:41 +08:00
|
|
|
let q1 = UnitQuaternion::from_scaled_axis(axis_angle1);
|
|
|
|
let q2 = UnitQuaternion::from_scaled_axis(axis_angle2);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-04-17 23:26:58 +08:00
|
|
|
assert!(na::approx_eq(&(q1 / q2).to_rotation_matrix(), &(r1 * r2)))
|
2014-10-15 03:37:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-04-17 23:26:58 +08:00
|
|
|
fn test_quaternion_to_axis_angle() {
|
2016-01-10 21:49:55 +08:00
|
|
|
for _ in 0usize .. 10000 {
|
2016-04-17 23:26:58 +08:00
|
|
|
let axis_angle: Vector3<f64> = random();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-08-16 16:48:41 +08:00
|
|
|
let q = UnitQuaternion::from_scaled_axis(axis_angle);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2015-01-10 05:52:44 +08:00
|
|
|
println!("{:?} {:?}", q.rotation(), axis_angle);
|
2014-10-15 03:37:44 +08:00
|
|
|
assert!(na::approx_eq(&q.rotation(), &axis_angle))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-04-17 23:26:58 +08:00
|
|
|
fn test_quaternion_euler_angles() {
|
2016-01-10 21:49:55 +08:00
|
|
|
for _ in 0usize .. 10000 {
|
2016-04-17 23:26:58 +08:00
|
|
|
let angles: Vector3<f64> = random();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-08-16 16:48:41 +08:00
|
|
|
let q = UnitQuaternion::from_euler_angles(angles.x, angles.y, angles.z);
|
|
|
|
let m = Rotation3::from_euler_angles(angles.x, angles.y, angles.z);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
2016-04-17 23:26:58 +08:00
|
|
|
assert!(na::approx_eq(&q.to_rotation_matrix(), &m))
|
2014-10-15 03:37:44 +08:00
|
|
|
}
|
|
|
|
}
|
2015-06-02 04:37:54 +08:00
|
|
|
|
|
|
|
#[test]
|
2016-04-17 23:26:58 +08:00
|
|
|
fn test_quaternion_rotation_between() {
|
|
|
|
let q1: UnitQuaternion<f64> = random();
|
|
|
|
let q2: UnitQuaternion<f64> = random();
|
2015-06-02 04:37:54 +08:00
|
|
|
|
|
|
|
let delta = na::rotation_between(&q1, &q2);
|
|
|
|
|
|
|
|
assert!(na::approx_eq(&(delta * q1), &q2))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2016-04-17 23:26:58 +08:00
|
|
|
fn test_quaternion_angle_between() {
|
|
|
|
let q1: UnitQuaternion<f64> = random();
|
|
|
|
let q2: UnitQuaternion<f64> = random();
|
2015-06-02 04:37:54 +08:00
|
|
|
|
|
|
|
let delta = na::rotation_between(&q1, &q2);
|
|
|
|
let delta_angle = na::angle_between(&q1, &q2);
|
|
|
|
|
|
|
|
assert!(na::approx_eq(&na::norm(&na::rotation(&delta)), &delta_angle))
|
|
|
|
}
|
2016-07-30 00:02:37 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_quaternion_exp_zero_is_one() {
|
|
|
|
let q = Quaternion::new(0., 0., 0., 0.);
|
|
|
|
assert!(na::approx_eq(&q.exp(), &one()))
|
|
|
|
}
|
2016-07-30 20:08:55 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_quaternion_neutral() {
|
|
|
|
for _ in 0 .. 10000 {
|
|
|
|
let q1: Quaternion<f32> = random();
|
|
|
|
let qi: Quaternion<f32> = one();
|
|
|
|
let q2 = q1 * qi;
|
|
|
|
let q3 = qi * q1;
|
|
|
|
|
|
|
|
assert!(na::approx_eq(&q1, &q2) && na::approx_eq(&q2, &q3))
|
|
|
|
}
|
|
|
|
}
|
2016-08-16 18:26:36 +08:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_quaternion_polar_decomposition() {
|
|
|
|
for _ in 0 .. 10000 {
|
|
|
|
let q1: Quaternion<f32> = random();
|
|
|
|
let decomp = q1.polar_decomposition();
|
|
|
|
let q2 = Quaternion::from_polar_decomposition(decomp.0, decomp.1, decomp.2);
|
|
|
|
|
|
|
|
assert!(na::approx_eq(&q1, &q2))
|
|
|
|
}
|
|
|
|
}
|