2013-11-25 22:31:46 +08:00
|
|
|
|
//! Quaternion definition.
|
|
|
|
|
|
2014-11-01 00:40:47 +08:00
|
|
|
|
#![allow(missing_docs)] // we allow missing to avoid having to document the dispatch trait.
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
|
|
|
|
use std::mem;
|
2014-12-24 02:01:49 +08:00
|
|
|
|
use std::slice::{Iter, IterMut};
|
2015-01-04 16:37:56 +08:00
|
|
|
|
use std::ops::{Add, Sub, Mul, Div, Neg, Index, IndexMut};
|
2015-02-21 07:02:27 +08:00
|
|
|
|
use std::iter::{FromIterator, IntoIterator};
|
2015-02-17 20:32:54 +08:00
|
|
|
|
use rand::{Rand, Rng};
|
2015-04-18 20:19:43 +08:00
|
|
|
|
use num::{Zero, One};
|
2014-11-26 21:17:34 +08:00
|
|
|
|
use structs::{Vec3, Pnt3, Rot3, Mat3};
|
2015-05-06 19:23:14 +08:00
|
|
|
|
use traits::operations::{ApproxEq, Inv, POrd, POrdering, Axpy};
|
2015-04-18 20:19:43 +08:00
|
|
|
|
use traits::structure::{Cast, Indexable, Iterable, IterableMut, Dim, Shape, BaseFloat, BaseNum,
|
2015-05-25 20:47:14 +08:00
|
|
|
|
Bounded, Repeat};
|
2015-11-16 04:38:23 +08:00
|
|
|
|
use traits::geometry::{Norm, Rotation, RotationMatrix, Rotate, RotationTo, Transform};
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
2015-01-10 08:36:13 +08:00
|
|
|
|
#[cfg(feature="arbitrary")]
|
|
|
|
|
use quickcheck::{Arbitrary, Gen};
|
|
|
|
|
|
|
|
|
|
|
2013-11-25 22:31:46 +08:00
|
|
|
|
/// A quaternion.
|
2015-03-02 04:50:17 +08:00
|
|
|
|
#[repr(C)]
|
2015-02-17 20:32:54 +08:00
|
|
|
|
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
2013-11-25 22:31:46 +08:00
|
|
|
|
pub struct Quat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
/// The scalar component of the quaternion.
|
|
|
|
|
pub w: N,
|
|
|
|
|
/// The first vector component of the quaternion.
|
|
|
|
|
pub i: N,
|
|
|
|
|
/// The second vector component of the quaternion.
|
|
|
|
|
pub j: N,
|
|
|
|
|
/// The third vector component of the quaternion.
|
|
|
|
|
pub k: N
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<N> Quat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
/// Creates a new quaternion from its components.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn new(w: N, i: N, j: N, k: N) -> Quat<N> {
|
2013-11-25 22:31:46 +08:00
|
|
|
|
Quat {
|
|
|
|
|
w: w,
|
|
|
|
|
i: i,
|
|
|
|
|
j: j,
|
|
|
|
|
k: k
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
|
|
|
|
/// The vector part `(i, j, k)` of this quaternion.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn vector<'a>(&'a self) -> &'a Vec3<N> {
|
|
|
|
|
// FIXME: do this require a `repr(C)` ?
|
|
|
|
|
unsafe {
|
|
|
|
|
mem::transmute(&self.i)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The scalar part `w` of this quaternion.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn scalar<'a>(&'a self) -> &'a N {
|
|
|
|
|
&self.w
|
|
|
|
|
}
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N: Neg<Output = N> + Copy> Quat<N> {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
/// Compute the conjugate of this quaternion.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn conjugate(&self) -> Quat<N> {
|
|
|
|
|
Quat { w: self.w, i: -self.i, j: -self.j, k: -self.k }
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
/// Replaces this quaternion by its conjugate.
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
pub fn conjugate_mut(&mut self) {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
self.i = -self.i;
|
|
|
|
|
self.j = -self.j;
|
|
|
|
|
self.k = -self.k;
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
|
impl<N: BaseFloat + ApproxEq<N>> Inv for Quat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn inv(&self) -> Option<Quat<N>> {
|
2014-12-18 06:28:32 +08:00
|
|
|
|
let mut res = *self;
|
|
|
|
|
|
2015-02-02 06:23:57 +08:00
|
|
|
|
if res.inv_mut() {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
Some(res)
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn inv_mut(&mut self) -> bool {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
let sqnorm = Norm::sqnorm(self);
|
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
|
if ApproxEq::approx_eq(&sqnorm, &::zero()) {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
false
|
|
|
|
|
}
|
|
|
|
|
else {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
self.conjugate_mut();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
self.w = self.w / sqnorm;
|
|
|
|
|
self.i = self.i / sqnorm;
|
|
|
|
|
self.j = self.j / sqnorm;
|
|
|
|
|
self.k = self.k / sqnorm;
|
|
|
|
|
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-15 22:47:59 +08:00
|
|
|
|
impl<N: BaseFloat> Norm<N> for Quat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-02 01:50:11 +08:00
|
|
|
|
fn sqnorm(&self) -> N {
|
|
|
|
|
self.w * self.w + self.i * self.i + self.j * self.j + self.k * self.k
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn normalize(&self) -> Quat<N> {
|
2014-12-02 01:50:11 +08:00
|
|
|
|
let n = self.norm();
|
|
|
|
|
Quat::new(self.w / n, self.i / n, self.j / n, self.k / n)
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn normalize_mut(&mut self) -> N {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
let n = Norm::norm(self);
|
|
|
|
|
|
|
|
|
|
self.w = self.w / n;
|
|
|
|
|
self.i = self.i / n;
|
|
|
|
|
self.j = self.j / n;
|
|
|
|
|
self.k = self.k / n;
|
|
|
|
|
|
|
|
|
|
n
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N> Mul<Quat<N>> for Quat<N>
|
|
|
|
|
where N: Copy + Mul<N, Output = N> + Sub<N, Output = N> + Add<N, Output = N> {
|
|
|
|
|
type Output = Quat<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn mul(self, right: Quat<N>) -> Quat<N> {
|
2013-11-25 22:31:46 +08:00
|
|
|
|
Quat::new(
|
2014-11-26 21:17:34 +08:00
|
|
|
|
self.w * right.w - self.i * right.i - self.j * right.j - self.k * right.k,
|
|
|
|
|
self.w * right.i + self.i * right.w + self.j * right.k - self.k * right.j,
|
|
|
|
|
self.w * right.j - self.i * right.k + self.j * right.w + self.k * right.i,
|
|
|
|
|
self.w * right.k + self.i * right.j - self.j * right.i + self.k * right.w)
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N: ApproxEq<N> + BaseFloat> Div<Quat<N>> for Quat<N> {
|
|
|
|
|
type Output = Quat<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn div(self, right: Quat<N>) -> Quat<N> {
|
2015-02-02 06:23:57 +08:00
|
|
|
|
self * right.inv().expect("Unable to invert the denominator.")
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 04:38:23 +08:00
|
|
|
|
rand_impl!(Quat, w, i, j, k);
|
|
|
|
|
|
2015-01-10 08:36:13 +08:00
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
/// A unit quaternion that can represent a 3D rotation.
|
2015-03-02 04:50:17 +08:00
|
|
|
|
#[repr(C)]
|
2015-02-01 23:15:55 +08:00
|
|
|
|
#[derive(Eq, PartialEq, RustcEncodable, RustcDecodable, Clone, Hash, Debug, Copy)]
|
2014-10-15 03:37:44 +08:00
|
|
|
|
pub struct UnitQuat<N> {
|
|
|
|
|
q: Quat<N>
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-15 22:47:59 +08:00
|
|
|
|
impl<N: BaseFloat> UnitQuat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
/// Creates a new unit quaternion from the axis-angle representation of a rotation.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn new(axisangle: Vec3<N>) -> UnitQuat<N> {
|
|
|
|
|
let sqang = Norm::sqnorm(&axisangle);
|
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
|
if ::is_zero(&sqang) {
|
|
|
|
|
::one()
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
let ang = sqang.sqrt();
|
2015-04-02 16:11:15 +08:00
|
|
|
|
let (s, c) = (ang / Cast::from(2.0)).sin_cos();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
|
|
|
|
let s_ang = s / ang;
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
UnitQuat::new_with_unit_quat(
|
|
|
|
|
Quat::new(
|
|
|
|
|
c,
|
|
|
|
|
axisangle.x * s_ang,
|
|
|
|
|
axisangle.y * s_ang,
|
|
|
|
|
axisangle.z * s_ang)
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a new unit quaternion from a quaternion.
|
|
|
|
|
///
|
|
|
|
|
/// The input quaternion will be normalized.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn new_with_quat(q: Quat<N>) -> UnitQuat<N> {
|
2015-02-17 20:54:56 +08:00
|
|
|
|
UnitQuat { q: q.normalize() }
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Creates a new unit quaternion from Euler angles.
|
|
|
|
|
///
|
|
|
|
|
/// The primitive rotations are applied in order: 1 roll − 2 pitch − 3 yaw.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn new_with_euler_angles(roll: N, pitch: N, yaw: N) -> UnitQuat<N> {
|
2015-04-02 16:11:15 +08:00
|
|
|
|
let _0_5: N = Cast::from(0.5);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
let (sr, cr) = (roll * _0_5).sin_cos();
|
|
|
|
|
let (sp, cp) = (pitch * _0_5).sin_cos();
|
|
|
|
|
let (sy, cy) = (yaw * _0_5).sin_cos();
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
UnitQuat::new_with_unit_quat(
|
|
|
|
|
Quat::new(
|
|
|
|
|
cr * cp * cy + sr * sp * sy,
|
|
|
|
|
sr * cp * cy - cr * sp * sy,
|
|
|
|
|
cr * sp * cy + sr * cp * sy,
|
|
|
|
|
cr * cp * sy - sr * sp * cy)
|
2013-11-25 22:31:46 +08:00
|
|
|
|
)
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Builds a rotation matrix from this quaternion.
|
|
|
|
|
pub fn to_rot(&self) -> Rot3<N> {
|
2015-04-02 16:11:15 +08:00
|
|
|
|
let _2: N = Cast::from(2.0);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
let ww = self.q.w * self.q.w;
|
|
|
|
|
let ii = self.q.i * self.q.i;
|
|
|
|
|
let jj = self.q.j * self.q.j;
|
|
|
|
|
let kk = self.q.k * self.q.k;
|
|
|
|
|
let ij = _2 * self.q.i * self.q.j;
|
|
|
|
|
let wk = _2 * self.q.w * self.q.k;
|
|
|
|
|
let wj = _2 * self.q.w * self.q.j;
|
|
|
|
|
let ik = _2 * self.q.i * self.q.k;
|
|
|
|
|
let jk = _2 * self.q.j * self.q.k;
|
|
|
|
|
let wi = _2 * self.q.w * self.q.i;
|
|
|
|
|
|
|
|
|
|
unsafe {
|
|
|
|
|
Rot3::new_with_mat(
|
|
|
|
|
Mat3::new(
|
|
|
|
|
ww + ii - jj - kk, ij - wk, wj + ik,
|
|
|
|
|
wk + ij, ww - ii + jj - kk, jk - wi,
|
|
|
|
|
ik - wj, wi + jk, ww - ii - jj + kk
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
}
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-02-17 20:32:54 +08:00
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
impl<N> UnitQuat<N> {
|
|
|
|
|
/// Creates a new unit quaternion from a quaternion.
|
|
|
|
|
///
|
|
|
|
|
/// This is unsafe because the input quaternion will not be normalized.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub unsafe fn new_with_unit_quat(q: Quat<N>) -> UnitQuat<N> {
|
|
|
|
|
UnitQuat {
|
|
|
|
|
q: q
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// The `Quat` representation of this unit quaternion.
|
|
|
|
|
#[inline]
|
|
|
|
|
pub fn quat<'a>(&'a self) -> &'a Quat<N> {
|
|
|
|
|
&self.q
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
|
impl<N: BaseNum> One for UnitQuat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn one() -> UnitQuat<N> {
|
|
|
|
|
unsafe {
|
2014-11-16 21:04:15 +08:00
|
|
|
|
UnitQuat::new_with_unit_quat(Quat::new(::one(), ::zero(), ::zero(), ::zero()))
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N: Copy + Neg<Output = N>> Inv for UnitQuat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn inv(&self) -> Option<UnitQuat<N>> {
|
2014-12-18 06:28:32 +08:00
|
|
|
|
let mut cpy = *self;
|
|
|
|
|
|
2015-02-02 06:23:57 +08:00
|
|
|
|
cpy.inv_mut();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
Some(cpy)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn inv_mut(&mut self) -> bool {
|
|
|
|
|
self.q.conjugate_mut();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
|
|
|
|
true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
|
impl<N: Rand + BaseFloat> Rand for UnitQuat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn rand<R: Rng>(rng: &mut R) -> UnitQuat<N> {
|
|
|
|
|
UnitQuat::new(rng.gen())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<N: ApproxEq<N>> ApproxEq<N> for UnitQuat<N> {
|
|
|
|
|
#[inline]
|
|
|
|
|
fn approx_epsilon(_: Option<UnitQuat<N>>) -> N {
|
|
|
|
|
ApproxEq::approx_epsilon(None::<N>)
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-01 05:08:42 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn approx_ulps(_: Option<UnitQuat<N>>) -> u32 {
|
|
|
|
|
ApproxEq::approx_ulps(None::<N>)
|
|
|
|
|
}
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-02 01:50:11 +08:00
|
|
|
|
fn approx_eq_eps(&self, other: &UnitQuat<N>, eps: &N) -> bool {
|
|
|
|
|
ApproxEq::approx_eq_eps(&self.q, &other.q, eps)
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
2015-01-01 05:08:42 +08:00
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn approx_eq_ulps(&self, other: &UnitQuat<N>, ulps: u32) -> bool {
|
|
|
|
|
ApproxEq::approx_eq_ulps(&self.q, &other.q, ulps)
|
|
|
|
|
}
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N: BaseFloat + ApproxEq<N>> Div<UnitQuat<N>> for UnitQuat<N> {
|
|
|
|
|
type Output = UnitQuat<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn div(self, other: UnitQuat<N>) -> UnitQuat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
UnitQuat { q: self.q / other.q }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N: BaseNum> Mul<UnitQuat<N>> for UnitQuat<N> {
|
|
|
|
|
type Output = UnitQuat<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn mul(self, right: UnitQuat<N>) -> UnitQuat<N> {
|
2014-11-26 21:17:34 +08:00
|
|
|
|
UnitQuat { q: self.q * right.q }
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N: BaseNum> Mul<Vec3<N>> for UnitQuat<N> {
|
|
|
|
|
type Output = Vec3<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn mul(self, right: Vec3<N>) -> Vec3<N> {
|
2014-11-16 21:04:15 +08:00
|
|
|
|
let _2: N = ::one::<N>() + ::one();
|
2014-12-18 06:28:32 +08:00
|
|
|
|
let mut t = ::cross(self.q.vector(), &right);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
t.x = t.x * _2;
|
|
|
|
|
t.y = t.y * _2;
|
|
|
|
|
t.z = t.z * _2;
|
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
|
Vec3::new(t.x * self.q.w, t.y * self.q.w, t.z * self.q.w) + ::cross(self.q.vector(), &t) + right
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-05 02:03:28 +08:00
|
|
|
|
impl<N: BaseNum> Mul<Pnt3<N>> for UnitQuat<N> {
|
|
|
|
|
type Output = Pnt3<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn mul(self, right: Pnt3<N>) -> Pnt3<N> {
|
|
|
|
|
::orig::<Pnt3<N>>() + self * *right.as_vec()
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 06:58:20 +08:00
|
|
|
|
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuat<N>> for Vec3<N> {
|
2015-01-05 02:03:28 +08:00
|
|
|
|
type Output = Vec3<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn mul(self, right: UnitQuat<N>) -> Vec3<N> {
|
|
|
|
|
let mut inv_quat = right;
|
|
|
|
|
|
2015-02-02 06:23:57 +08:00
|
|
|
|
inv_quat.inv_mut();
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
|
inv_quat * self
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 06:58:20 +08:00
|
|
|
|
impl<N: BaseNum + Neg<Output = N>> Mul<UnitQuat<N>> for Pnt3<N> {
|
2015-01-05 02:03:28 +08:00
|
|
|
|
type Output = Pnt3<N>;
|
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
2014-12-18 06:28:32 +08:00
|
|
|
|
fn mul(self, right: UnitQuat<N>) -> Pnt3<N> {
|
|
|
|
|
::orig::<Pnt3<N>>() + *self.as_vec() * right
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-12-18 06:28:32 +08:00
|
|
|
|
impl<N: BaseFloat> Rotation<Vec3<N>> for UnitQuat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn rotation(&self) -> Vec3<N> {
|
2014-11-16 21:04:15 +08:00
|
|
|
|
let _2 = ::one::<N>() + ::one();
|
2014-12-18 06:28:32 +08:00
|
|
|
|
let mut v = *self.q.vector();
|
2015-02-02 06:23:57 +08:00
|
|
|
|
let ang = _2 * v.normalize_mut().atan2(self.q.w);
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
2014-11-16 21:04:15 +08:00
|
|
|
|
if ::is_zero(&ang) {
|
|
|
|
|
::zero()
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Vec3::new(v.x * ang, v.y * ang, v.z * ang)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn inv_rotation(&self) -> Vec3<N> {
|
|
|
|
|
-self.rotation()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn append_rotation_mut(&mut self, amount: &Vec3<N>) {
|
|
|
|
|
*self = Rotation::append_rotation(self, amount)
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn append_rotation(&self, amount: &Vec3<N>) -> UnitQuat<N> {
|
2014-12-18 06:28:32 +08:00
|
|
|
|
*self * UnitQuat::new(*amount)
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn prepend_rotation_mut(&mut self, amount: &Vec3<N>) {
|
|
|
|
|
*self = Rotation::prepend_rotation(self, amount)
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
2015-02-02 06:23:57 +08:00
|
|
|
|
fn prepend_rotation(&self, amount: &Vec3<N>) -> UnitQuat<N> {
|
2014-12-18 06:28:32 +08:00
|
|
|
|
UnitQuat::new(*amount) * *self
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn set_rotation(&mut self, v: Vec3<N>) {
|
|
|
|
|
*self = UnitQuat::new(v)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-11-16 04:38:23 +08:00
|
|
|
|
impl<N: BaseFloat> RotationMatrix<N, Vec3<N>, Vec3<N>> for UnitQuat<N> {
|
|
|
|
|
type Output = Rot3<N>;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn to_rot_mat(&self) -> Rot3<N> {
|
|
|
|
|
self.to_rot()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 06:58:20 +08:00
|
|
|
|
impl<N: BaseNum + Neg<Output = N>> Rotate<Vec3<N>> for UnitQuat<N> {
|
2013-11-25 22:31:46 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn rotate(&self, v: &Vec3<N>) -> Vec3<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
*self * *v
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn inv_rotate(&self, v: &Vec3<N>) -> Vec3<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
*v * *self
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 06:58:20 +08:00
|
|
|
|
impl<N: BaseNum + Neg<Output = N>> Rotate<Pnt3<N>> for UnitQuat<N> {
|
2013-11-25 22:31:46 +08:00
|
|
|
|
#[inline]
|
2014-10-15 03:37:44 +08:00
|
|
|
|
fn rotate(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
|
|
|
|
*self * *p
|
|
|
|
|
}
|
2013-11-25 22:31:46 +08:00
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn inv_rotate(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
|
|
|
|
*p * *self
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
2014-10-15 03:37:44 +08:00
|
|
|
|
}
|
2013-11-25 22:31:46 +08:00
|
|
|
|
|
2015-06-01 04:52:18 +08:00
|
|
|
|
impl<N: BaseFloat + ApproxEq<N>> RotationTo for UnitQuat<N> {
|
|
|
|
|
type AngleType = N;
|
|
|
|
|
type DeltaRotationType = UnitQuat<N>;
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn angle_to(&self, other: &Self) -> N {
|
|
|
|
|
let delta = self.rotation_to(other);
|
|
|
|
|
let _2 = ::one::<N>() + ::one();
|
|
|
|
|
|
|
|
|
|
_2 * delta.q.vector().norm().atan2(delta.q.w)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn rotation_to(&self, other: &Self) -> UnitQuat<N> {
|
|
|
|
|
*other / *self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 06:58:20 +08:00
|
|
|
|
impl<N: BaseNum + Neg<Output = N>> Transform<Vec3<N>> for UnitQuat<N> {
|
2013-11-25 22:31:46 +08:00
|
|
|
|
#[inline]
|
2014-10-15 03:37:44 +08:00
|
|
|
|
fn transform(&self, v: &Vec3<N>) -> Vec3<N> {
|
|
|
|
|
*self * *v
|
|
|
|
|
}
|
2013-11-25 22:31:46 +08:00
|
|
|
|
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn inv_transform(&self, v: &Vec3<N>) -> Vec3<N> {
|
|
|
|
|
*v * *self
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-04 06:58:20 +08:00
|
|
|
|
impl<N: BaseNum + Neg<Output = N>> Transform<Pnt3<N>> for UnitQuat<N> {
|
2014-10-15 03:37:44 +08:00
|
|
|
|
#[inline]
|
|
|
|
|
fn transform(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
|
|
|
|
*self * *p
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline]
|
|
|
|
|
fn inv_transform(&self, p: &Pnt3<N>) -> Pnt3<N> {
|
|
|
|
|
*p * *self
|
2013-11-25 22:31:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2014-10-15 03:37:44 +08:00
|
|
|
|
|
2015-01-10 08:36:13 +08:00
|
|
|
|
#[cfg(feature="arbitrary")]
|
|
|
|
|
impl<N: Arbitrary + BaseFloat> Arbitrary for UnitQuat<N> {
|
|
|
|
|
fn arbitrary<G: Gen>(g: &mut G) -> UnitQuat<N> {
|
|
|
|
|
UnitQuat::new(Arbitrary::arbitrary(g))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2014-12-19 22:33:01 +08:00
|
|
|
|
ord_impl!(Quat, w, i, j, k);
|
|
|
|
|
vec_axis_impl!(Quat, w, i, j, k);
|
|
|
|
|
vec_cast_impl!(Quat, w, i, j, k);
|
|
|
|
|
as_array_impl!(Quat, 4);
|
|
|
|
|
index_impl!(Quat);
|
|
|
|
|
indexable_impl!(Quat, 4);
|
|
|
|
|
at_fast_impl!(Quat, 4);
|
2015-05-25 20:47:14 +08:00
|
|
|
|
repeat_impl!(Quat, val, w, i, j, k);
|
2014-12-19 22:33:01 +08:00
|
|
|
|
dim_impl!(Quat, 3);
|
|
|
|
|
container_impl!(Quat);
|
|
|
|
|
add_impl!(Quat, w, i, j, k);
|
|
|
|
|
sub_impl!(Quat, w, i, j, k);
|
|
|
|
|
scalar_add_impl!(Quat, w, i, j, k);
|
|
|
|
|
scalar_sub_impl!(Quat, w, i, j, k);
|
|
|
|
|
scalar_mul_impl!(Quat, w, i, j, k);
|
|
|
|
|
scalar_div_impl!(Quat, w, i, j, k);
|
|
|
|
|
neg_impl!(Quat, w, i, j, k);
|
|
|
|
|
zero_one_impl!(Quat, w, i, j, k);
|
|
|
|
|
approx_eq_impl!(Quat, w, i, j, k);
|
|
|
|
|
from_iterator_impl!(Quat, iterator, iterator, iterator, iterator);
|
|
|
|
|
bounded_impl!(Quat, w, i, j, k);
|
|
|
|
|
axpy_impl!(Quat, w, i, j, k);
|
|
|
|
|
iterable_impl!(Quat, 4);
|
|
|
|
|
iterable_mut_impl!(Quat, 4);
|
2015-01-10 08:36:13 +08:00
|
|
|
|
arbitrary_impl!(Quat, w, i, j, k);
|
2014-12-19 22:33:01 +08:00
|
|
|
|
|
|
|
|
|
dim_impl!(UnitQuat, 3);
|