2020-12-16 22:02:02 +08:00
|
|
|
use crate::{Quaternion, SimdRealField};
|
2020-12-19 01:19:38 +08:00
|
|
|
#[cfg(feature = "serde-serialize")]
|
|
|
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
2020-12-16 22:02:02 +08:00
|
|
|
|
|
|
|
/// A dual quaternion.
|
|
|
|
///
|
|
|
|
/// # Indexing
|
|
|
|
///
|
|
|
|
/// DualQuaternions are stored as \[..real, ..dual\].
|
2020-12-18 23:09:56 +08:00
|
|
|
/// Both of the quaternion components are laid out in `i, j, k, w` order.
|
2020-12-16 22:02:02 +08:00
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use nalgebra::{DualQuaternion, Quaternion};
|
|
|
|
///
|
|
|
|
/// let real = Quaternion::new(1.0, 2.0, 3.0, 4.0);
|
|
|
|
/// let dual = Quaternion::new(5.0, 6.0, 7.0, 8.0);
|
|
|
|
///
|
|
|
|
/// let dq = DualQuaternion::from_real_and_dual(real, dual);
|
2020-12-18 23:09:56 +08:00
|
|
|
/// assert_eq!(dq[0], 2.0);
|
|
|
|
/// assert_eq!(dq[1], 3.0);
|
|
|
|
///
|
|
|
|
/// assert_eq!(dq[4], 6.0);
|
|
|
|
/// assert_eq!(dq[7], 5.0);
|
2020-12-16 22:02:02 +08:00
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// 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, Default, Eq, PartialEq, Copy, Clone)]
|
|
|
|
pub struct DualQuaternion<N: SimdRealField> {
|
2020-12-18 23:09:56 +08:00
|
|
|
/// The real component of the quaternion
|
|
|
|
pub real: Quaternion<N>,
|
|
|
|
/// The dual component of the quaternion
|
|
|
|
pub dual: Quaternion<N>,
|
2020-12-16 22:02:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl<N: SimdRealField> DualQuaternion<N>
|
|
|
|
where
|
|
|
|
N::Element: SimdRealField,
|
|
|
|
{
|
|
|
|
/// Normalizes this quaternion.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
/// ```
|
|
|
|
/// # #[macro_use] extern crate approx;
|
|
|
|
/// # use nalgebra::{DualQuaternion, Quaternion};
|
|
|
|
/// let real = Quaternion::new(1.0, 2.0, 3.0, 4.0);
|
|
|
|
/// let dual = Quaternion::new(5.0, 6.0, 7.0, 8.0);
|
|
|
|
/// let dq = DualQuaternion::from_real_and_dual(real, dual);
|
|
|
|
///
|
|
|
|
/// let dq_normalized = dq.normalize();
|
|
|
|
///
|
2020-12-18 23:09:56 +08:00
|
|
|
/// relative_eq!(dq_normalized.real.norm(), 1.0);
|
2020-12-16 22:02:02 +08:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
#[must_use = "Did you mean to use normalize_mut()?"]
|
|
|
|
pub fn normalize(&self) -> Self {
|
2020-12-18 23:09:56 +08:00
|
|
|
let real_norm = self.real.norm();
|
2020-12-16 22:02:02 +08:00
|
|
|
|
2020-12-18 23:09:56 +08:00
|
|
|
Self::from_real_and_dual(self.real / real_norm, self.dual / real_norm)
|
2020-12-16 22:02:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// Normalizes this quaternion.
|
|
|
|
///
|
|
|
|
/// # Example
|
|
|
|
/// ```
|
|
|
|
/// # #[macro_use] extern crate approx;
|
|
|
|
/// # use nalgebra::{DualQuaternion, Quaternion};
|
|
|
|
/// let real = Quaternion::new(1.0, 2.0, 3.0, 4.0);
|
|
|
|
/// let dual = Quaternion::new(5.0, 6.0, 7.0, 8.0);
|
|
|
|
/// let mut dq = DualQuaternion::from_real_and_dual(real, dual);
|
|
|
|
///
|
|
|
|
/// dq.normalize_mut();
|
|
|
|
///
|
2020-12-18 23:09:56 +08:00
|
|
|
/// relative_eq!(dq.real.norm(), 1.0);
|
2020-12-16 22:02:02 +08:00
|
|
|
/// ```
|
|
|
|
#[inline]
|
|
|
|
pub fn normalize_mut(&mut self) {
|
|
|
|
*self = self.normalize();
|
|
|
|
}
|
|
|
|
}
|
2020-12-19 01:19:38 +08:00
|
|
|
|
|
|
|
#[cfg(feature = "serde-serialize")]
|
|
|
|
impl<N: SimdRealField> Serialize for DualQuaternion<N>
|
|
|
|
where
|
|
|
|
N: Serialize,
|
|
|
|
{
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
|
|
|
|
where
|
|
|
|
S: Serializer,
|
|
|
|
{
|
|
|
|
self.as_ref().serialize(serializer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(feature = "serde-serialize")]
|
|
|
|
impl<'a, N: SimdRealField> Deserialize<'a> for DualQuaternion<N>
|
|
|
|
where
|
|
|
|
N: Deserialize<'a>,
|
|
|
|
{
|
|
|
|
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
|
|
|
where
|
|
|
|
Des: Deserializer<'a>,
|
|
|
|
{
|
|
|
|
type Dq<N> = [N; 8];
|
|
|
|
|
|
|
|
let dq: Dq<N> = Dq::<N>::deserialize(deserializer)?;
|
|
|
|
|
|
|
|
Ok(Self {
|
|
|
|
real: Quaternion::new(dq[3], dq[0], dq[1], dq[2]),
|
|
|
|
dual: Quaternion::new(dq[7], dq[4], dq[5], dq[6]),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|