Struct vek::quaternion::repr_simd::Quaternion
source · #[repr(simd)]pub struct Quaternion<T> {
pub x: T,
pub y: T,
pub z: T,
pub w: T,
}
Expand description
Quaternions are a convenient representation for rotations in 3D spaces.
IMPORTANT: Quaternions are only valid as rotations as long as they are normalized (i.e their magnitude is 1). Most operations assume this, instead of normalizing inputs behind your back, so be careful.
They essentially consist of a vector part (x
, y
, z
), and scalar part (w
).
For unit quaternions, the vector part is the unit axis of rotation scaled by the sine of
the half-angle of the rotation, and the scalar part is the cosine of the half-angle.
Fields§
§x: T
§y: T
§z: T
§w: T
Implementations§
source§impl<T> Quaternion<T>
impl<T> Quaternion<T>
sourcepub fn from_xyzw(x: T, y: T, z: T, w: T) -> Self
pub fn from_xyzw(x: T, y: T, z: T, w: T) -> Self
Creates a new quaternion with x
, y
, z
and w
elements in order.
You are responsible for ensuring that the resulting quaternion is normalized.
sourcepub fn from_scalar_and_vec3<V: Into<Vec3<T>>>(pair: (T, V)) -> Self
pub fn from_scalar_and_vec3<V: Into<Vec3<T>>>(pair: (T, V)) -> Self
Creates a new quaternion from a scalar-and-vector pair.
You are responsible for ensuring that the resulting quaternion is normalized.
sourcepub fn into_scalar_and_vec3(self) -> (T, Vec3<T>)
pub fn into_scalar_and_vec3(self) -> (T, Vec3<T>)
Converts this quaternion into a scalar-and-vector pair by destructuring.
Not to be confused with into_angle_axis()
.
sourcepub fn zero() -> Selfwhere
T: Zero,
pub fn zero() -> Selfwhere T: Zero,
Creates a new quaternion with all elements set to zero.
Be careful: since it has a magnitude equal to zero, it is not valid to use for most operations.
sourcepub fn identity() -> Selfwhere
T: Zero + One,
pub fn identity() -> Selfwhere T: Zero + One,
Creates the identity quaternion.
use std::f32::consts::PI;
let id = Quaternion::<f32>::identity();
assert_eq!(id, Default::default());
assert_relative_eq!(id, id.conjugate());
assert_relative_eq!(id, id.inverse());
let q = Quaternion::rotation_y(PI);
assert_relative_eq!(id * q, q);
assert_relative_eq!(q * id, q);
sourcepub fn conjugate(self) -> Selfwhere
T: Neg<Output = T>,
pub fn conjugate(self) -> Selfwhere T: Neg<Output = T>,
Gets this quaternion’s conjugate (copy with negated vector part).
On normalized quaternions, the conjugate also happens to be the inverse.
use std::f32::consts::PI;
let p = Quaternion::rotation_x(PI);
let q = Quaternion::rotation_z(PI);
assert_relative_eq!((p*q).conjugate(), q.conjugate() * p.conjugate());
// Rotation quaternions are normalized, so their conjugate is also their inverse.
assert_relative_eq!(q.conjugate(), q.inverse());
sourcepub fn inverse(self) -> Selfwhere
T: Neg<Output = T> + Copy + Add<T, Output = T> + Mul<Output = T> + Div<Output = T>,
pub fn inverse(self) -> Selfwhere T: Neg<Output = T> + Copy + Add<T, Output = T> + Mul<Output = T> + Div<Output = T>,
Gets this quaternion’s inverse, i.e the one that reverses its effect.
On normalized quaternions, the inverse happens to be the conjugate.
use std::f32::consts::PI;
let rot = Quaternion::rotation_y(PI);
let inv = rot.inverse();
assert_relative_eq!(rot*inv, Quaternion::identity());
assert_relative_eq!(inv*rot, Quaternion::identity());
let p = Quaternion::rotation_x(PI);
let q = Quaternion::rotation_z(PI);
assert_relative_eq!((p*q).inverse(), q.inverse() * p.inverse());
sourcepub fn dot(self, q: Self) -> Twhere
T: Copy + Add<T, Output = T> + Mul<Output = T>,
pub fn dot(self, q: Self) -> Twhere T: Copy + Add<T, Output = T> + Mul<Output = T>,
Gets the dot product between two quaternions.
sourcepub fn normalized(self) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn normalized(self) -> Selfwhere T: Real + Add<T, Output = T>,
Gets a normalized copy of this quaternion.
sourcepub fn magnitude_squared(self) -> Twhere
T: Real + Add<T, Output = T>,
pub fn magnitude_squared(self) -> Twhere T: Real + Add<T, Output = T>,
Gets this quaternion’s magnitude, squared.
sourcepub fn magnitude(self) -> Twhere
T: Real + Add<T, Output = T>,
pub fn magnitude(self) -> Twhere T: Real + Add<T, Output = T>,
Gets this quaternion’s magnitude.
sourcepub fn rotation_from_to_3d<V: Into<Vec3<T>>>(from: V, to: V) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotation_from_to_3d<V: Into<Vec3<T>>>(from: V, to: V) -> Selfwhere T: Real + Add<T, Output = T>,
Creates a quaternion that would rotate a from
direction to to
.
let (from, to) = (Vec4::<f32>::unit_x(), Vec4::<f32>::unit_y());
let q = Quaternion::<f32>::rotation_from_to_3d(from, to);
assert_relative_eq!(q * from, to);
assert_relative_eq!(q * Vec4::unit_y(), -Vec4::unit_x());
let (from, to) = (Vec4::<f32>::unit_x(), -Vec4::<f32>::unit_x());
let q = Quaternion::<f32>::rotation_from_to_3d(from, to);
assert_relative_eq!(q * from, to);
sourcepub fn rotation_3d<V: Into<Vec3<T>>>(angle_radians: T, axis: V) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotation_3d<V: Into<Vec3<T>>>(angle_radians: T, axis: V) -> Selfwhere T: Real + Add<T, Output = T>,
Creates a quaternion from an angle and axis. The axis is not required to be normalized.
sourcepub fn rotation_x(angle_radians: T) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotation_x(angle_radians: T) -> Selfwhere T: Real + Add<T, Output = T>,
Creates a quaternion from an angle for a rotation around the X axis.
sourcepub fn rotation_y(angle_radians: T) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotation_y(angle_radians: T) -> Selfwhere T: Real + Add<T, Output = T>,
Creates a quaternion from an angle for a rotation around the Y axis.
sourcepub fn rotation_z(angle_radians: T) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotation_z(angle_radians: T) -> Selfwhere T: Real + Add<T, Output = T>,
Creates a quaternion from an angle for a rotation around the Y axis.
sourcepub fn rotated_3d<V: Into<Vec3<T>>>(self, angle_radians: T, axis: V) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotated_3d<V: Into<Vec3<T>>>(self, angle_radians: T, axis: V) -> Selfwhere T: Real + Add<T, Output = T>,
Returns this quaternion rotated around the given axis with given angle. The axis is not required to be normalized.
sourcepub fn rotated_x(self, angle_radians: T) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotated_x(self, angle_radians: T) -> Selfwhere T: Real + Add<T, Output = T>,
Returns this quaternion rotated around the X axis with given angle.
sourcepub fn rotated_y(self, angle_radians: T) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotated_y(self, angle_radians: T) -> Selfwhere T: Real + Add<T, Output = T>,
Returns this quaternion rotated around the Y axis with given angle.
sourcepub fn rotated_z(self, angle_radians: T) -> Selfwhere
T: Real + Add<T, Output = T>,
pub fn rotated_z(self, angle_radians: T) -> Selfwhere T: Real + Add<T, Output = T>,
Returns this quaternion rotated around the Z axis with given angle.
sourcepub fn rotate_3d<V: Into<Vec3<T>>>(&mut self, angle_radians: T, axis: V)where
T: Real + Add<T, Output = T>,
pub fn rotate_3d<V: Into<Vec3<T>>>(&mut self, angle_radians: T, axis: V)where T: Real + Add<T, Output = T>,
Rotates this quaternion around the given axis with given angle. The axis is not required to be normalized.
sourcepub fn rotate_x(&mut self, angle_radians: T)where
T: Real + Add<T, Output = T>,
pub fn rotate_x(&mut self, angle_radians: T)where T: Real + Add<T, Output = T>,
Rotates this quaternion around the X axis with given angle.
sourcepub fn rotate_y(&mut self, angle_radians: T)where
T: Real + Add<T, Output = T>,
pub fn rotate_y(&mut self, angle_radians: T)where T: Real + Add<T, Output = T>,
Rotates this quaternion around the Y axis with given angle.
sourcepub fn rotate_z(&mut self, angle_radians: T)where
T: Real + Add<T, Output = T>,
pub fn rotate_z(&mut self, angle_radians: T)where T: Real + Add<T, Output = T>,
Rotates this quaternion around the Z axis with given angle.
sourcepub fn into_angle_axis(self) -> (T, Vec3<T>)where
T: Real,
pub fn into_angle_axis(self) -> (T, Vec3<T>)where T: Real,
Convert this quaternion to angle-axis representation, assuming the quaternion is normalized.
use std::f32::consts::PI;
let q = Quaternion::rotation_x(PI/2.);
let (angle, axis) = q.into_angle_axis();
assert_relative_eq!(angle, PI/2.);
assert_relative_eq!(axis, Vec3::unit_x());
let angle = PI*4./5.;
let axis = Vec3::new(1_f32, 2., 3.);
let q = Quaternion::rotation_3d(angle, axis);
let (a, v) = q.into_angle_axis();
assert_relative_eq!(a, angle);
assert_relative_eq!(v, axis.normalized());
source§impl<T> Quaternion<T>where
T: Copy + One + Mul<Output = T> + Sub<Output = T> + MulAdd<T, T, Output = T>,
impl<T> Quaternion<T>where T: Copy + One + Mul<Output = T> + Sub<Output = T> + MulAdd<T, T, Output = T>,
sourcepub fn lerp_precise_unnormalized(from: Self, to: Self, factor: T) -> Selfwhere
T: Clamp + Zero,
pub fn lerp_precise_unnormalized(from: Self, to: Self, factor: T) -> Selfwhere T: Clamp + Zero,
Performs linear interpolation without normalizing the result, using an implementation that supposedly yields a more precise result.
This is probably not what you’re looking for.
For an implementation that normalizes the result (which is more commonly wanted), see the Lerp
implementation.
sourcepub fn lerp_unclamped_precise_unnormalized(
from: Self,
to: Self,
factor: T
) -> Self
pub fn lerp_unclamped_precise_unnormalized( from: Self, to: Self, factor: T ) -> Self
Performs linear interpolation without normalizing the result and without
implicitly constraining factor
to be between 0 and 1,
using an implementation that supposedly yields a more precise result.
This is probably not what you’re looking for.
For an implementation that normalizes the result (which is more commonly wanted), see the Lerp
implementation.
source§impl<T> Quaternion<T>where
T: Copy + Sub<Output = T> + MulAdd<T, T, Output = T>,
impl<T> Quaternion<T>where T: Copy + Sub<Output = T> + MulAdd<T, T, Output = T>,
sourcepub fn lerp_unnormalized(from: Self, to: Self, factor: T) -> Selfwhere
T: Clamp + Zero + One,
pub fn lerp_unnormalized(from: Self, to: Self, factor: T) -> Selfwhere T: Clamp + Zero + One,
Performs linear interpolation without normalizing the result.
This is probably not what you’re looking for.
For an implementation that normalizes the result (which is more commonly wanted), see the Lerp
implementation.
sourcepub fn lerp_unclamped_unnormalized(from: Self, to: Self, factor: T) -> Self
pub fn lerp_unclamped_unnormalized(from: Self, to: Self, factor: T) -> Self
Performs linear interpolation without normalizing the result and without
implicitly constraining factor
to be between 0 and 1.
This is probably not what you’re looking for.
For an implementation that normalizes the result (which is more commonly wanted), see the Lerp
implementation.
source§impl<T> Quaternion<T>where
T: Lerp<T, Output = T> + Add<T, Output = T> + Real,
impl<T> Quaternion<T>where T: Lerp<T, Output = T> + Add<T, Output = T> + Real,
sourcepub fn slerp_unclamped(from: Self, to: Self, factor: T) -> Self
pub fn slerp_unclamped(from: Self, to: Self, factor: T) -> Self
Performs spherical linear interpolation without implictly constraining factor
to
be between 0 and 1.
use std::f32::consts::PI;
let from = Quaternion::rotation_z(0_f32);
let to = Quaternion::rotation_z(PI*9./10.);
let angles = 32;
for i in 0..angles {
let factor = (i as f32) / (angles as f32);
let expected = Quaternion::rotation_z(factor * PI*9./10.);
let slerp = Quaternion::slerp(from, to, factor);
assert_relative_eq!(slerp, expected);
}
Trait Implementations§
source§impl<T: AbsDiffEq> AbsDiffEq<Quaternion<T>> for Quaternion<T>where
T::Epsilon: Copy,
impl<T: AbsDiffEq> AbsDiffEq<Quaternion<T>> for Quaternion<T>where T::Epsilon: Copy,
source§fn default_epsilon() -> T::Epsilon
fn default_epsilon() -> T::Epsilon
source§fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool
fn abs_diff_eq(&self, other: &Self, epsilon: Self::Epsilon) -> bool
source§fn abs_diff_ne(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool
fn abs_diff_ne(&self, other: &Rhs, epsilon: Self::Epsilon) -> bool
AbsDiffEq::abs_diff_eq
.source§impl<T> Add<Quaternion<T>> for Quaternion<T>where
T: Add<Output = T>,
impl<T> Add<Quaternion<T>> for Quaternion<T>where T: Add<Output = T>,
source§impl<T: Clone> Clone for Quaternion<T>
impl<T: Clone> Clone for Quaternion<T>
source§fn clone(&self) -> Quaternion<T>
fn clone(&self) -> Quaternion<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<T: Debug> Debug for Quaternion<T>
impl<T: Debug> Debug for Quaternion<T>
source§impl<T: Zero + One> Default for Quaternion<T>
impl<T: Zero + One> Default for Quaternion<T>
The default value for a quaternion is the identity.
assert_eq!(Quaternion::<f32>::identity(), Quaternion::default());
source§impl<'de, T> Deserialize<'de> for Quaternion<T>where
T: Deserialize<'de>,
impl<'de, T> Deserialize<'de> for Quaternion<T>where T: Deserialize<'de>,
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,
source§impl<T> From<Quaternion<T>> for CVec3<T>
impl<T> From<Quaternion<T>> for CVec3<T>
A Vec3
can be created directly from a quaternion’s x
, y
and z
elements.
source§fn from(v: Quaternion<T>) -> Self
fn from(v: Quaternion<T>) -> Self
source§impl<T> From<Quaternion<T>> for CVec4<T>
impl<T> From<Quaternion<T>> for CVec4<T>
A Vec4
can be created directly from a quaternion’s x
, y
, z
and w
elements.
source§fn from(v: Quaternion<T>) -> Self
fn from(v: Quaternion<T>) -> Self
source§impl<T> From<Quaternion<T>> for Mat3<T>where
T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
impl<T> From<Quaternion<T>> for Mat3<T>where T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
source§fn from(q: Quaternion<T>) -> Self
fn from(q: Quaternion<T>) -> Self
source§impl<T> From<Quaternion<T>> for Mat3<T>where
T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
impl<T> From<Quaternion<T>> for Mat3<T>where T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
source§fn from(q: Quaternion<T>) -> Self
fn from(q: Quaternion<T>) -> Self
source§impl<T> From<Quaternion<T>> for Mat4<T>where
T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
impl<T> From<Quaternion<T>> for Mat4<T>where T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
Rotation matrices can be obtained from quaternions. This implementation only works properly if the quaternion is normalized.
use std::f32::consts::PI;
let angles = 32;
for i in 0..angles {
let theta = PI * 2. * (i as f32) / (angles as f32);
assert_relative_eq!(Mat4::rotation_x(theta), Mat4::from(Quaternion::rotation_x(theta)), epsilon = 0.000001);
assert_relative_eq!(Mat4::rotation_y(theta), Mat4::from(Quaternion::rotation_y(theta)), epsilon = 0.000001);
assert_relative_eq!(Mat4::rotation_z(theta), Mat4::from(Quaternion::rotation_z(theta)), epsilon = 0.000001);
assert_relative_eq!(Mat4::rotation_x(theta), Mat4::rotation_3d(theta, Vec4::unit_x()));
assert_relative_eq!(Mat4::rotation_y(theta), Mat4::rotation_3d(theta, Vec4::unit_y()));
assert_relative_eq!(Mat4::rotation_z(theta), Mat4::rotation_3d(theta, Vec4::unit_z()));
// See what rotating unit vectors do for most angles between 0 and 2*PI.
// It's helpful to picture this as a right-handed coordinate system.
let v = Vec4::unit_y();
let m = Mat4::rotation_x(theta);
assert_relative_eq!(m * v, Vec4::new(0., theta.cos(), theta.sin(), 0.));
let v = Vec4::unit_z();
let m = Mat4::rotation_y(theta);
assert_relative_eq!(m * v, Vec4::new(theta.sin(), 0., theta.cos(), 0.));
let v = Vec4::unit_x();
let m = Mat4::rotation_z(theta);
assert_relative_eq!(m * v, Vec4::new(theta.cos(), theta.sin(), 0., 0.));
}
source§fn from(q: Quaternion<T>) -> Self
fn from(q: Quaternion<T>) -> Self
source§impl<T> From<Quaternion<T>> for Mat4<T>where
T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
impl<T> From<Quaternion<T>> for Mat4<T>where T: Copy + Zero + One + Mul<Output = T> + Add<Output = T> + Sub<Output = T>,
Rotation matrices can be obtained from quaternions. This implementation only works properly if the quaternion is normalized.
use std::f32::consts::PI;
let angles = 32;
for i in 0..angles {
let theta = PI * 2. * (i as f32) / (angles as f32);
assert_relative_eq!(Mat4::rotation_x(theta), Mat4::from(Quaternion::rotation_x(theta)), epsilon = 0.000001);
assert_relative_eq!(Mat4::rotation_y(theta), Mat4::from(Quaternion::rotation_y(theta)), epsilon = 0.000001);
assert_relative_eq!(Mat4::rotation_z(theta), Mat4::from(Quaternion::rotation_z(theta)), epsilon = 0.000001);
assert_relative_eq!(Mat4::rotation_x(theta), Mat4::rotation_3d(theta, Vec4::unit_x()));
assert_relative_eq!(Mat4::rotation_y(theta), Mat4::rotation_3d(theta, Vec4::unit_y()));
assert_relative_eq!(Mat4::rotation_z(theta), Mat4::rotation_3d(theta, Vec4::unit_z()));
// See what rotating unit vectors do for most angles between 0 and 2*PI.
// It's helpful to picture this as a right-handed coordinate system.
let v = Vec4::unit_y();
let m = Mat4::rotation_x(theta);
assert_relative_eq!(m * v, Vec4::new(0., theta.cos(), theta.sin(), 0.));
let v = Vec4::unit_z();
let m = Mat4::rotation_y(theta);
assert_relative_eq!(m * v, Vec4::new(theta.sin(), 0., theta.cos(), 0.));
let v = Vec4::unit_x();
let m = Mat4::rotation_z(theta);
assert_relative_eq!(m * v, Vec4::new(theta.cos(), theta.sin(), 0., 0.));
}
source§fn from(q: Quaternion<T>) -> Self
fn from(q: Quaternion<T>) -> Self
source§impl<T> From<Quaternion<T>> for Vec3<T>
impl<T> From<Quaternion<T>> for Vec3<T>
A Vec3
can be created directly from a quaternion’s x
, y
and z
elements.
source§fn from(v: Quaternion<T>) -> Self
fn from(v: Quaternion<T>) -> Self
source§impl<T> From<Quaternion<T>> for Vec4<T>
impl<T> From<Quaternion<T>> for Vec4<T>
A Vec4
can be created directly from a quaternion’s x
, y
, z
and w
elements.
source§fn from(v: Quaternion<T>) -> Self
fn from(v: Quaternion<T>) -> Self
source§impl<T> From<Vec4<T>> for Quaternion<T>
impl<T> From<Vec4<T>> for Quaternion<T>
A quaternion can be created directly from a Vec4
’s x
, y
, z
and w
elements.
You are responsible for ensuring that the resulting quaternion is normalized.
source§impl<T> From<Vec4<T>> for Quaternion<T>
impl<T> From<Vec4<T>> for Quaternion<T>
A quaternion can be created directly from a Vec4
’s x
, y
, z
and w
elements.
You are responsible for ensuring that the resulting quaternion is normalized.
source§impl<T: Hash> Hash for Quaternion<T>
impl<T: Hash> Hash for Quaternion<T>
source§impl<'a, T, Factor> Lerp<Factor> for &'a Quaternion<T>where
T: Lerp<Factor, Output = T> + Add<T, Output = T> + Real,
Factor: Copy,
impl<'a, T, Factor> Lerp<Factor> for &'a Quaternion<T>where T: Lerp<Factor, Output = T> + Add<T, Output = T> + Real, Factor: Copy,
The Lerp
implementation for quaternion is the “Normalized LERP”.
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn lerp_unclamped_precise(from: Self, to: Self, factor: Factor) -> Quaternion<T>
fn lerp_unclamped_precise(from: Self, to: Self, factor: Factor) -> Quaternion<T>
from
to to
with factor
unconstrained,
using a possibly slower but more precise operation. Read moresource§fn lerp_unclamped(from: Self, to: Self, factor: Factor) -> Quaternion<T>
fn lerp_unclamped(from: Self, to: Self, factor: Factor) -> Quaternion<T>
from
to to
with factor
unconstrained,
using the supposedly fastest but less precise implementation. Read moresource§fn lerp_unclamped_inclusive_range(
range: RangeInclusive<Self>,
factor: Factor
) -> Self::Output
fn lerp_unclamped_inclusive_range( range: RangeInclusive<Self>, factor: Factor ) -> Self::Output
lerp_unclamped()
that used a single RangeInclusive
parameter instead of two values.source§fn lerp_unclamped_precise_inclusive_range(
range: RangeInclusive<Self>,
factor: Factor
) -> Self::Output
fn lerp_unclamped_precise_inclusive_range( range: RangeInclusive<Self>, factor: Factor ) -> Self::Output
lerp_unclamped_precise()
that used a single RangeInclusive
parameter instead of two values.source§impl<T, Factor> Lerp<Factor> for Quaternion<T>where
T: Lerp<Factor, Output = T> + Add<T, Output = T> + Real,
Factor: Copy,
impl<T, Factor> Lerp<Factor> for Quaternion<T>where T: Lerp<Factor, Output = T> + Add<T, Output = T> + Real, Factor: Copy,
The Lerp
implementation for quaternion is the “Normalized LERP”.
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn lerp_unclamped_precise(from: Self, to: Self, factor: Factor) -> Self
fn lerp_unclamped_precise(from: Self, to: Self, factor: Factor) -> Self
from
to to
with factor
unconstrained,
using a possibly slower but more precise operation. Read moresource§fn lerp_unclamped(from: Self, to: Self, factor: Factor) -> Self
fn lerp_unclamped(from: Self, to: Self, factor: Factor) -> Self
from
to to
with factor
unconstrained,
using the supposedly fastest but less precise implementation. Read moresource§fn lerp_unclamped_inclusive_range(
range: RangeInclusive<Self>,
factor: Factor
) -> Self::Output
fn lerp_unclamped_inclusive_range( range: RangeInclusive<Self>, factor: Factor ) -> Self::Output
lerp_unclamped()
that used a single RangeInclusive
parameter instead of two values.source§fn lerp_unclamped_precise_inclusive_range(
range: RangeInclusive<Self>,
factor: Factor
) -> Self::Output
fn lerp_unclamped_precise_inclusive_range( range: RangeInclusive<Self>, factor: Factor ) -> Self::Output
lerp_unclamped_precise()
that used a single RangeInclusive
parameter instead of two values.source§impl<T> Mul<Quaternion<T>> for Quaternion<T>where
T: Copy + Mul<Output = T> + Sub<Output = T> + Zero + Add<T, Output = T>,
impl<T> Mul<Quaternion<T>> for Quaternion<T>where T: Copy + Mul<Output = T> + Sub<Output = T> + Zero + Add<T, Output = T>,
The Mul
implementation for quaternions is concatenation, a.k.a Grassman product.
use std::f32::consts::PI;
let v = Vec4::unit_x();
let p = Quaternion::rotation_y(PI/2.);
let q = Quaternion::rotation_z(PI/2.);
assert_relative_eq!((p*q)*v, p*(q*v));
assert_relative_eq!(p*q*v, Vec4::unit_y());
assert_relative_eq!(q*p*v, -Vec4::unit_z());
source§impl<T: Real + Add<T, Output = T>> Mul<Vec3<T>> for Quaternion<T>
impl<T: Real + Add<T, Output = T>> Mul<Vec3<T>> for Quaternion<T>
3D vectors can be rotated by being premultiplied by a quaternion, assuming the quaternion is normalized.
source§impl<T: Real + Add<T, Output = T>> Mul<Vec3<T>> for Quaternion<T>
impl<T: Real + Add<T, Output = T>> Mul<Vec3<T>> for Quaternion<T>
3D vectors can be rotated by being premultiplied by a quaternion, assuming the quaternion is normalized.
source§impl<T: Real + Add<T, Output = T>> Mul<Vec4<T>> for Quaternion<T>
impl<T: Real + Add<T, Output = T>> Mul<Vec4<T>> for Quaternion<T>
3D vectors can be rotated by being premultiplied by a quaternion, assuming the
quaternion is normalized.
On Vec4
s, the w
element is preserved, so you can safely rotate
points and directions.
use std::f32::consts::PI;
let v = Vec4::unit_x();
let q = Quaternion::<f32>::identity();
assert_relative_eq!(q * v, v);
let q = Quaternion::rotation_z(PI);
assert_relative_eq!(q * v, -v);
let q = Quaternion::rotation_z(PI * 0.5);
assert_relative_eq!(q * v, Vec4::unit_y());
let q = Quaternion::rotation_z(PI * 1.5);
assert_relative_eq!(q * v, -Vec4::unit_y());
let angles = 32;
for i in 0..angles {
let theta = PI * 2. * (i as f32) / (angles as f32);
// See what rotating unit vectors do for most angles between 0 and 2*PI.
// It's helpful to picture this as a right-handed coordinate system.
let v = Vec4::unit_y();
let q = Quaternion::rotation_x(theta);
assert_relative_eq!(q * v, Vec4::new(0., theta.cos(), theta.sin(), 0.));
let v = Vec4::unit_z();
let q = Quaternion::rotation_y(theta);
assert_relative_eq!(q * v, Vec4::new(theta.sin(), 0., theta.cos(), 0.));
let v = Vec4::unit_x();
let q = Quaternion::rotation_z(theta);
assert_relative_eq!(q * v, Vec4::new(theta.cos(), theta.sin(), 0., 0.));
}
source§impl<T: Real + Add<T, Output = T>> Mul<Vec4<T>> for Quaternion<T>
impl<T: Real + Add<T, Output = T>> Mul<Vec4<T>> for Quaternion<T>
3D vectors can be rotated by being premultiplied by a quaternion, assuming the
quaternion is normalized.
On Vec4
s, the w
element is preserved, so you can safely rotate
points and directions.
use std::f32::consts::PI;
let v = Vec4::unit_x();
let q = Quaternion::<f32>::identity();
assert_relative_eq!(q * v, v);
let q = Quaternion::rotation_z(PI);
assert_relative_eq!(q * v, -v);
let q = Quaternion::rotation_z(PI * 0.5);
assert_relative_eq!(q * v, Vec4::unit_y());
let q = Quaternion::rotation_z(PI * 1.5);
assert_relative_eq!(q * v, -Vec4::unit_y());
let angles = 32;
for i in 0..angles {
let theta = PI * 2. * (i as f32) / (angles as f32);
// See what rotating unit vectors do for most angles between 0 and 2*PI.
// It's helpful to picture this as a right-handed coordinate system.
let v = Vec4::unit_y();
let q = Quaternion::rotation_x(theta);
assert_relative_eq!(q * v, Vec4::new(0., theta.cos(), theta.sin(), 0.));
let v = Vec4::unit_z();
let q = Quaternion::rotation_y(theta);
assert_relative_eq!(q * v, Vec4::new(theta.sin(), 0., theta.cos(), 0.));
let v = Vec4::unit_x();
let q = Quaternion::rotation_z(theta);
assert_relative_eq!(q * v, Vec4::new(theta.cos(), theta.sin(), 0., 0.));
}
source§impl<T> Neg for Quaternion<T>where
T: Neg<Output = T>,
impl<T> Neg for Quaternion<T>where T: Neg<Output = T>,
source§impl<T: PartialEq> PartialEq<Quaternion<T>> for Quaternion<T>
impl<T: PartialEq> PartialEq<Quaternion<T>> for Quaternion<T>
source§fn eq(&self, other: &Quaternion<T>) -> bool
fn eq(&self, other: &Quaternion<T>) -> bool
self
and other
values to be equal, and is used
by ==
.source§impl<T: RelativeEq> RelativeEq<Quaternion<T>> for Quaternion<T>where
T::Epsilon: Copy,
impl<T: RelativeEq> RelativeEq<Quaternion<T>> for Quaternion<T>where T::Epsilon: Copy,
source§fn default_max_relative() -> T::Epsilon
fn default_max_relative() -> T::Epsilon
source§fn relative_eq(
&self,
other: &Self,
epsilon: T::Epsilon,
max_relative: T::Epsilon
) -> bool
fn relative_eq( &self, other: &Self, epsilon: T::Epsilon, max_relative: T::Epsilon ) -> bool
source§fn relative_ne(
&self,
other: &Rhs,
epsilon: Self::Epsilon,
max_relative: Self::Epsilon
) -> bool
fn relative_ne( &self, other: &Rhs, epsilon: Self::Epsilon, max_relative: Self::Epsilon ) -> bool
RelativeEq::relative_eq
.source§impl<T> Serialize for Quaternion<T>where
T: Serialize,
impl<T> Serialize for Quaternion<T>where T: Serialize,
source§impl<'a, T, Factor> Slerp<Factor> for &'a Quaternion<T>where
T: Lerp<T, Output = T> + Add<T, Output = T> + Real,
Factor: Into<T>,
impl<'a, T, Factor> Slerp<Factor> for &'a Quaternion<T>where T: Lerp<T, Output = T> + Add<T, Output = T> + Real, Factor: Into<T>,
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn slerp_unclamped(from: Self, to: Self, factor: Factor) -> Quaternion<T>
fn slerp_unclamped(from: Self, to: Self, factor: Factor) -> Quaternion<T>
factor
to
be between 0 and 1.source§impl<T, Factor> Slerp<Factor> for Quaternion<T>where
T: Lerp<T, Output = T> + Add<T, Output = T> + Real,
Factor: Into<T>,
impl<T, Factor> Slerp<Factor> for Quaternion<T>where T: Lerp<T, Output = T> + Add<T, Output = T> + Real, Factor: Into<T>,
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn slerp_unclamped(from: Self, to: Self, factor: Factor) -> Self
fn slerp_unclamped(from: Self, to: Self, factor: Factor) -> Self
factor
to
be between 0 and 1.