Add UnitQuaternion::{new_eps, from_scaled_axis_eps}.

This commit is contained in:
Sébastien Crozet 2018-05-03 12:06:11 +02:00
parent e995cdee06
commit 31e3547401
3 changed files with 36 additions and 3 deletions

View File

@ -7,6 +7,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
## [0.15.0] - WIP ## [0.15.0] - WIP
### Modified ### Modified
### Added ### Added
* Add `UnitQuaternion` constructor `::new_eps(...)` and `::from_scaled_axis_eps(...)` that return the
identity if the magnitude of the input axisangle is smaller than the epsilon provided.
* Add methods `.rotation_between_axis(...)` and `.scaled_rotation_between_axis(...)` to `UnitComplex` * Add methods `.rotation_between_axis(...)` and `.scaled_rotation_between_axis(...)` to `UnitComplex`
to compute the rotation matrix between two 2D **unit** vectors. to compute the rotation matrix between two 2D **unit** vectors.
* Add methods `.axis_angle()` to `UnitComplex` and `UnitQuaternion` in order to retrieve both the * Add methods `.axis_angle()` to `UnitComplex` and `UnitQuaternion` in order to retrieve both the

View File

@ -201,10 +201,16 @@ impl<N: Real> Quaternion<N> {
/// Compute the exponential of a quaternion. /// Compute the exponential of a quaternion.
#[inline] #[inline]
pub fn exp(&self) -> Quaternion<N> { pub fn exp(&self) -> Quaternion<N> {
self.exp_eps(N::default_epsilon())
}
/// Compute the exponential of a quaternion.
#[inline]
pub fn exp_eps(&self, eps: N) -> Quaternion<N> {
let v = self.vector(); let v = self.vector();
let nn = v.norm_squared(); let nn = v.norm_squared();
if relative_eq!(nn, N::zero()) { if nn <= eps * eps {
Quaternion::identity() Quaternion::identity()
} else { } else {
let w_exp = self.scalar().exp(); let w_exp = self.scalar().exp();

View File

@ -351,7 +351,7 @@ impl<N: Real> UnitQuaternion<N> {
/// Creates a new unit quaternion rotation from a rotation axis scaled by the rotation angle. /// Creates a new unit quaternion rotation from a rotation axis scaled by the rotation angle.
/// ///
/// If `axisangle` is zero, this returns the indentity rotation. /// If `axisangle` has a magnitude smaller than `N::default_epsilon()`, this returns the indentity rotation.
#[inline] #[inline]
pub fn new<SB>(axisangle: Vector<N, U3, SB>) -> Self pub fn new<SB>(axisangle: Vector<N, U3, SB>) -> Self
where where
@ -364,7 +364,20 @@ impl<N: Real> UnitQuaternion<N> {
/// Creates a new unit quaternion rotation from a rotation axis scaled by the rotation angle. /// Creates a new unit quaternion rotation from a rotation axis scaled by the rotation angle.
/// ///
/// If `axisangle` is zero, this returns the indentity rotation. /// If `axisangle` has a magnitude smaller than `eps`, this returns the indentity rotation.
#[inline]
pub fn new_eps<SB>(axisangle: Vector<N, U3, SB>, eps: N) -> Self
where
SB: Storage<N, U3>,
{
let two: N = ::convert(2.0f64);
let q = Quaternion::<N>::from_parts(N::zero(), axisangle / two).exp_eps(eps);
Self::new_unchecked(q)
}
/// Creates a new unit quaternion rotation from a rotation axis scaled by the rotation angle.
///
/// If `axisangle` has a magnitude smalle than `N::default_epsilon()`, this returns the indentity rotation.
/// Same as `Self::new(axisangle)`. /// Same as `Self::new(axisangle)`.
#[inline] #[inline]
pub fn from_scaled_axis<SB>(axisangle: Vector<N, U3, SB>) -> Self pub fn from_scaled_axis<SB>(axisangle: Vector<N, U3, SB>) -> Self
@ -373,6 +386,18 @@ impl<N: Real> UnitQuaternion<N> {
{ {
Self::new(axisangle) Self::new(axisangle)
} }
/// Creates a new unit quaternion rotation from a rotation axis scaled by the rotation angle.
///
/// If `axisangle` has a mangnitude smaller than `eps`, this returns the indentity rotation.
/// Same as `Self::new(axisangle)`.
#[inline]
pub fn from_scaled_axis_eps<SB>(axisangle: Vector<N, U3, SB>, eps: N) -> Self
where
SB: Storage<N, U3>,
{
Self::new_eps(axisangle, eps)
}
} }
impl<N: Real> One for UnitQuaternion<N> { impl<N: Real> One for UnitQuaternion<N> {