forked from M-Labs/nalgebra
Merge pull request #193 from phaazon/master
Added exp(), log() and powf() for Quaternion. + fixed One and Zero instances for Quaternion.
This commit is contained in:
commit
d05ad00c41
@ -568,6 +568,49 @@ impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuaternion<N> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Quaternion<f32> {
|
||||||
|
/// Compute the exponential of a quaternion.
|
||||||
|
pub fn exp(&self) -> Self {
|
||||||
|
let v = *self.vector();
|
||||||
|
let nn = v.norm_squared();
|
||||||
|
|
||||||
|
if nn.is_zero() {
|
||||||
|
::one()
|
||||||
|
} else {
|
||||||
|
let n = nn.sqrt();
|
||||||
|
let nv = v / n * n.sin();
|
||||||
|
Quaternion::new(n.cos(), nv.x, nv.y, nv.z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compute the natural logarithm (a.k.a ln()) of a quaternion.
|
||||||
|
///
|
||||||
|
/// Becareful, this function yields a `Quaternion<f32>`, losing the unit property.
|
||||||
|
pub fn log(&self) -> Self {
|
||||||
|
(Quaternion { w: 0., .. *self }).normalize() * self.w.acos()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Raise the quaternion to a given floating power.
|
||||||
|
pub fn powf(&self, n: f32) -> Self {
|
||||||
|
(self.log() * n).exp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> Zero for Quaternion<T> where T: Zero {
|
||||||
|
fn zero() -> Self {
|
||||||
|
Quaternion::new(::zero(), ::zero(), ::zero(), ::zero())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_zero(&self) -> bool {
|
||||||
|
self.w.is_zero() && self.i.is_zero() && self.j.is_zero() && self.k.is_zero()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> One for Quaternion<T> where T: Copy + One + Zero + Sub<T, Output = T> + Add<T, Output = T> {
|
||||||
|
fn one() -> Self {
|
||||||
|
Quaternion::new(T::one(), T::zero(), T::zero(), T::zero())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pord_impl!(Quaternion, w, i, j, k);
|
pord_impl!(Quaternion, w, i, j, k);
|
||||||
vec_axis_impl!(Quaternion, w, i, j, k);
|
vec_axis_impl!(Quaternion, w, i, j, k);
|
||||||
@ -586,7 +629,6 @@ scalar_sub_impl!(Quaternion, w, i, j, k);
|
|||||||
scalar_mul_impl!(Quaternion, w, i, j, k);
|
scalar_mul_impl!(Quaternion, w, i, j, k);
|
||||||
scalar_div_impl!(Quaternion, w, i, j, k);
|
scalar_div_impl!(Quaternion, w, i, j, k);
|
||||||
neg_impl!(Quaternion, w, i, j, k);
|
neg_impl!(Quaternion, w, i, j, k);
|
||||||
zero_one_impl!(Quaternion, w, i, j, k);
|
|
||||||
approx_eq_impl!(Quaternion, w, i, j, k);
|
approx_eq_impl!(Quaternion, w, i, j, k);
|
||||||
from_iterator_impl!(Quaternion, iterator, iterator, iterator, iterator);
|
from_iterator_impl!(Quaternion, iterator, iterator, iterator, iterator);
|
||||||
bounded_impl!(Quaternion, w, i, j, k);
|
bounded_impl!(Quaternion, w, i, j, k);
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
extern crate nalgebra as na;
|
extern crate nalgebra as na;
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
|
|
||||||
use na::{Point3, Vector3, Rotation3, UnitQuaternion, Rotation};
|
use na::{Point3, Quaternion, Vector3, Rotation3, UnitQuaternion, Rotation, one};
|
||||||
use rand::random;
|
use rand::random;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -90,3 +90,21 @@ fn test_quaternion_angle_between() {
|
|||||||
|
|
||||||
assert!(na::approx_eq(&na::norm(&na::rotation(&delta)), &delta_angle))
|
assert!(na::approx_eq(&na::norm(&na::rotation(&delta)), &delta_angle))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_quaternion_exp_zero_is_one() {
|
||||||
|
let q = Quaternion::new(0., 0., 0., 0.);
|
||||||
|
assert!(na::approx_eq(&q.exp(), &one()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user