Skip to content

Commit

Permalink
Introduce DualQuaternion type
Browse files Browse the repository at this point in the history
This commit introduces the `DualQuaternion` type, in line with the plan
laid out in [#487].

[#487]: #487
  • Loading branch information
chinedufn committed Dec 16, 2020
1 parent dda1ae7 commit 2017356
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/geometry/dual_quaternion.rs
@@ -0,0 +1,46 @@
use crate::{Quaternion, RealField, Scalar, SimdRealField};
use simba::simd::SimdValue;

/// A dual quaternion.
///
/// NOTE:
/// As of December 2020, dual quaternion support is a work in progress.
/// If a feature that you need is missing, feel free to open an issue or a PR.
/// See https://github.com/dimforge/nalgebra/issues/487
#[repr(C)]
#[derive(Debug)]
pub struct DualQuaternion<N: Scalar + SimdValue> {
/// The rotation part of the dual quaternion.
pub rot: Quaternion<N>,
/// The translation part of the dual quaternion.
pub trans: Quaternion<N>,
}

impl<N: RealField> Default for DualQuaternion<N> {
fn default() -> Self {
Self::identity()
}
}

impl<N: SimdRealField + Eq> Eq for DualQuaternion<N> where N::Element: SimdRealField {}

impl<N: SimdRealField> PartialEq for DualQuaternion<N>
where
N::Element: SimdRealField,
{
fn eq(&self, rhs: &Self) -> bool {
self.rot == rhs.rot && self.trans == rhs.trans
}
}

impl<N: Scalar + Copy + SimdValue> Copy for DualQuaternion<N> {}

impl<N: Scalar + SimdValue> Clone for DualQuaternion<N> {
#[inline]
fn clone(&self) -> Self {
Self {
rot: self.rot.clone(),
trans: self.trans.clone(),
}
}
}
46 changes: 46 additions & 0 deletions src/geometry/dual_quaternion_construction.rs
@@ -0,0 +1,46 @@
use crate::{DualQuaternion, Quaternion, Scalar, SimdRealField};
use simba::simd::SimdValue;

impl<N: Scalar + SimdValue> DualQuaternion<N> {
/// Creates a dual quaternion from its rotation and translation components.
///
/// # Example
/// ```
/// # use nalgebra::{DualQuaternion, Quaternion};
/// let rot = Quaternion::new(1.0, 2.0, 3.0, 4.0);
/// let trans = Quaternion::new(5.0, 6.0, 7.0, 8.0);
///
/// let dq = DualQuaternion::new(rot, trans);
/// assert_eq!(dq.rot.w, 1.0);
/// ```
#[inline]
pub fn new(rot: Quaternion<N>, trans: Quaternion<N>) -> Self {
Self { rot, trans }
}
}

impl<N: SimdRealField> DualQuaternion<N> {
/// The dual quaternion multiplicative identity
///
/// # Example
///
/// ```
/// # use nalgebra::{DualQuaternion, Quaternion};
///
/// let dq1 = DualQuaternion::identity();
/// let dq2 = DualQuaternion::new(
/// Quaternion::new(1.,2.,3.,4.),
/// Quaternion::new(5.,6.,7.,8.)
/// );
///
/// assert_eq!(dq1 * dq2, dq2);
/// assert_eq!(dq2 * dq1, dq2);
/// ```
#[inline]
pub fn identity() -> Self {
Self {
rot: Quaternion::from_real(N::one()),
trans: Quaternion::from_real(N::zero()),
}
}
}
30 changes: 30 additions & 0 deletions src/geometry/dual_quaternion_ops.rs
@@ -0,0 +1,30 @@
/*
* This file provides:
* NOTE: Work in progress https://github.com/dimforge/nalgebra/issues/487
*
* References:
* Multiplication:
* - https://cs.gmu.edu/~jmlien/teaching/cs451/uploads/Main/dual-quaternion.pdf
* ===================
*
*/

use crate::base::allocator::Allocator;
use crate::{DefaultAllocator, DualQuaternion, Scalar, SimdRealField, U1, U4};
use simba::simd::SimdValue;
use std::ops::Mul;

impl<N: Scalar + SimdValue + SimdRealField> Mul<DualQuaternion<N>> for DualQuaternion<N>
where
N::Element: Scalar + SimdValue + SimdRealField,
DefaultAllocator: Allocator<N, U4, U1> + Allocator<N, U4, U1>,
{
type Output = DualQuaternion<N>;

fn mul(self, rhs: Self) -> Self::Output {
Self {
rot: self.rot * rhs.rot,
trans: self.rot * rhs.trans + rhs.rot * self.trans,
}
}
}
6 changes: 6 additions & 0 deletions src/geometry/mod.rs
Expand Up @@ -35,6 +35,10 @@ mod quaternion_coordinates;
mod quaternion_ops;
mod quaternion_simba;

mod dual_quaternion;
mod dual_quaternion_construction;
mod dual_quaternion_ops;

mod unit_complex;
#[cfg(feature = "alga")]
mod unit_complex_alga;
Expand Down Expand Up @@ -98,6 +102,8 @@ pub use self::rotation_alias::*;

pub use self::quaternion::*;

pub use self::dual_quaternion::*;

pub use self::unit_complex::*;

pub use self::translation::*;
Expand Down

0 comments on commit 2017356

Please sign in to comment.