Struct veloren_voxygen_anim::vek::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) -> Quaternion<T>
pub fn from_xyzw(x: T, y: T, z: T, w: T) -> Quaternion<T>
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>(pair: (T, V)) -> Quaternion<T>
pub fn from_scalar_and_vec3<V>(pair: (T, V)) -> Quaternion<T>
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() -> Quaternion<T>where
T: Zero,
pub fn zero() -> Quaternion<T>where
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() -> Quaternion<T>
pub fn identity() -> Quaternion<T>
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) -> Quaternion<T>where
T: Neg<Output = T>,
pub fn conjugate(self) -> Quaternion<T>where
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) -> Quaternion<T>
pub fn inverse(self) -> Quaternion<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: Quaternion<T>) -> T
pub fn dot(self, q: Quaternion<T>) -> T
Gets the dot product between two quaternions.
sourcepub fn normalized(self) -> Quaternion<T>
pub fn normalized(self) -> Quaternion<T>
Gets a normalized copy of this quaternion.
sourcepub fn magnitude_squared(self) -> T
pub fn magnitude_squared(self) -> T
Gets this quaternion’s magnitude, squared.
sourcepub fn rotation_from_to_3d<V>(from: V, to: V) -> Quaternion<T>
pub fn rotation_from_to_3d<V>(from: V, to: V) -> Quaternion<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>(angle_radians: T, axis: V) -> Quaternion<T>
pub fn rotation_3d<V>(angle_radians: T, axis: V) -> Quaternion<T>
Creates a quaternion from an angle and axis. The axis is not required to be normalized.
sourcepub fn rotation_x(angle_radians: T) -> Quaternion<T>
pub fn rotation_x(angle_radians: T) -> Quaternion<T>
Creates a quaternion from an angle for a rotation around the X axis.
sourcepub fn rotation_y(angle_radians: T) -> Quaternion<T>
pub fn rotation_y(angle_radians: T) -> Quaternion<T>
Creates a quaternion from an angle for a rotation around the Y axis.
sourcepub fn rotation_z(angle_radians: T) -> Quaternion<T>
pub fn rotation_z(angle_radians: T) -> Quaternion<T>
Creates a quaternion from an angle for a rotation around the Y axis.
sourcepub fn rotated_3d<V>(self, angle_radians: T, axis: V) -> Quaternion<T>
pub fn rotated_3d<V>(self, angle_radians: T, axis: V) -> Quaternion<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) -> Quaternion<T>
pub fn rotated_x(self, angle_radians: T) -> Quaternion<T>
Returns this quaternion rotated around the X axis with given angle.
sourcepub fn rotated_y(self, angle_radians: T) -> Quaternion<T>
pub fn rotated_y(self, angle_radians: T) -> Quaternion<T>
Returns this quaternion rotated around the Y axis with given angle.
sourcepub fn rotated_z(self, angle_radians: T) -> Quaternion<T>
pub fn rotated_z(self, angle_radians: T) -> Quaternion<T>
Returns this quaternion rotated around the Z axis with given angle.
sourcepub fn rotate_3d<V>(&mut self, angle_radians: T, axis: V)
pub fn rotate_3d<V>(&mut self, angle_radians: T, axis: V)
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)
pub fn rotate_x(&mut self, angle_radians: T)
Rotates this quaternion around the X axis with given angle.
sourcepub fn rotate_y(&mut self, angle_radians: T)
pub fn rotate_y(&mut self, angle_radians: T)
Rotates this quaternion around the Y axis with given angle.
sourcepub fn rotate_z(&mut self, angle_radians: T)
pub fn rotate_z(&mut self, angle_radians: 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());
sourcepub fn from_vec4(v: Vec4<T>) -> Quaternion<T>
pub fn from_vec4(v: Vec4<T>) -> Quaternion<T>
Creates a quaternion from a Vec4
by destructuring.
You are responsible for ensuring that the resulting quaternion is normalized.
source§impl<T> Quaternion<T>
impl<T> Quaternion<T>
sourcepub fn lerp_precise_unnormalized(
from: Quaternion<T>,
to: Quaternion<T>,
factor: T,
) -> Quaternion<T>
pub fn lerp_precise_unnormalized( from: Quaternion<T>, to: Quaternion<T>, factor: T, ) -> Quaternion<T>
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: Quaternion<T>,
to: Quaternion<T>,
factor: T,
) -> Quaternion<T>
pub fn lerp_unclamped_precise_unnormalized( from: Quaternion<T>, to: Quaternion<T>, factor: T, ) -> Quaternion<T>
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>
impl<T> Quaternion<T>
sourcepub fn lerp_unnormalized(
from: Quaternion<T>,
to: Quaternion<T>,
factor: T,
) -> Quaternion<T>
pub fn lerp_unnormalized( from: Quaternion<T>, to: Quaternion<T>, factor: T, ) -> Quaternion<T>
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: Quaternion<T>,
to: Quaternion<T>,
factor: T,
) -> Quaternion<T>
pub fn lerp_unclamped_unnormalized( from: Quaternion<T>, to: Quaternion<T>, factor: T, ) -> Quaternion<T>
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>
impl<T> Quaternion<T>
sourcepub fn slerp_unclamped(
from: Quaternion<T>,
to: Quaternion<T>,
factor: T,
) -> Quaternion<T>
pub fn slerp_unclamped( from: Quaternion<T>, to: Quaternion<T>, factor: T, ) -> Quaternion<T>
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);
}
sourcepub fn slerp(from: Quaternion<T>, to: Quaternion<T>, factor: T) -> Quaternion<T>where
T: Clamp,
pub fn slerp(from: Quaternion<T>, to: Quaternion<T>, factor: T) -> Quaternion<T>where
T: Clamp,
Perform spherical linear interpolation, constraining factor
to
be between 0 and 1.
Trait Implementations§
source§impl<T> AbsDiffEq for Quaternion<T>where
T: AbsDiffEq,
<T as AbsDiffEq>::Epsilon: Copy,
impl<T> AbsDiffEq for Quaternion<T>where
T: AbsDiffEq,
<T as AbsDiffEq>::Epsilon: Copy,
source§fn default_epsilon() -> <T as AbsDiffEq>::Epsilon
fn default_epsilon() -> <T as AbsDiffEq>::Epsilon
source§fn abs_diff_eq(
&self,
other: &Quaternion<T>,
epsilon: <Quaternion<T> as AbsDiffEq>::Epsilon,
) -> bool
fn abs_diff_eq( &self, other: &Quaternion<T>, epsilon: <Quaternion<T> as AbsDiffEq>::Epsilon, ) -> bool
§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 for Quaternion<T>where
T: Add<Output = T>,
impl<T> Add for Quaternion<T>where
T: Add<Output = T>,
§type Output = Quaternion<T>
type Output = Quaternion<T>
+
operator.source§fn add(self, rhs: Quaternion<T>) -> <Quaternion<T> as Add>::Output
fn add(self, rhs: Quaternion<T>) -> <Quaternion<T> as Add>::Output
+
operation. Read moresource§impl<T> Clone for Quaternion<T>where
T: Clone,
impl<T> Clone for Quaternion<T>where
T: Clone,
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 for Quaternion<T>where
T: Debug,
impl<T> Debug for Quaternion<T>where
T: Debug,
source§impl<T> Default for Quaternion<T>
impl<T> Default for Quaternion<T>
The default value for a quaternion is the identity.
assert_eq!(Quaternion::<f32>::identity(), Quaternion::default());
source§fn default() -> Quaternion<T>
fn default() -> Quaternion<T>
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<Quaternion<T>, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Quaternion<T>, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
source§impl<T> Div<T> for Quaternion<T>
impl<T> Div<T> for Quaternion<T>
§type Output = Quaternion<T>
type Output = Quaternion<T>
/
operator.§impl From<Ori> for Quaternion<f32>
impl From<Ori> for Quaternion<f32>
§fn from(_: Ori) -> Quaternion<f32>
fn from(_: Ori) -> Quaternion<f32>
source§impl<T> From<Quaternion<T>> for Mat4<T>
impl<T> From<Quaternion<T>> for Mat4<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>) -> Mat4<T>
fn from(q: Quaternion<T>) -> Mat4<T>
source§impl<T> From<Quaternion<T>> for Quaternion<T>
impl<T> From<Quaternion<T>> for Quaternion<T>
source§fn from(q: Quaternion<T>) -> Quaternion<T>
fn from(q: Quaternion<T>) -> Quaternion<T>
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>) -> Vec3<T>
fn from(v: Quaternion<T>) -> Vec3<T>
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>) -> Vec3<T>
fn from(v: Quaternion<T>) -> Vec3<T>
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>) -> Vec4<T>
fn from(v: Quaternion<T>) -> Vec4<T>
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§fn from(v: Vec4<T>) -> Quaternion<T>
fn from(v: Vec4<T>) -> Quaternion<T>
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§fn from(v: Vec4<T>) -> Quaternion<T>
fn from(v: Vec4<T>) -> Quaternion<T>
source§impl<T> Hash for Quaternion<T>where
T: Hash,
impl<T> Hash for Quaternion<T>where
T: Hash,
source§impl<T> Into<Quaternion<T>> for Quaternion<T>
impl<T> Into<Quaternion<T>> for Quaternion<T>
source§impl<'a, T, Factor> Lerp<Factor> for &'a Quaternion<T>
impl<'a, T, Factor> Lerp<Factor> for &'a Quaternion<T>
The Lerp
implementation for quaternion is the “Normalized LERP”.
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn lerp_unclamped_precise(
from: &'a Quaternion<T>,
to: &'a Quaternion<T>,
factor: Factor,
) -> Quaternion<T>
fn lerp_unclamped_precise( from: &'a Quaternion<T>, to: &'a Quaternion<T>, factor: Factor, ) -> Quaternion<T>
from
to to
with factor
unconstrained,
using a possibly slower but more precise operation. Read moresource§fn lerp_unclamped(
from: &'a Quaternion<T>,
to: &'a Quaternion<T>,
factor: Factor,
) -> Quaternion<T>
fn lerp_unclamped( from: &'a Quaternion<T>, to: &'a Quaternion<T>, 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>
impl<T, Factor> Lerp<Factor> for Quaternion<T>
The Lerp
implementation for quaternion is the “Normalized LERP”.
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn lerp_unclamped_precise(
from: Quaternion<T>,
to: Quaternion<T>,
factor: Factor,
) -> Quaternion<T>
fn lerp_unclamped_precise( from: Quaternion<T>, to: Quaternion<T>, factor: Factor, ) -> Quaternion<T>
from
to to
with factor
unconstrained,
using a possibly slower but more precise operation. Read moresource§fn lerp_unclamped(
from: Quaternion<T>,
to: Quaternion<T>,
factor: Factor,
) -> Quaternion<T>
fn lerp_unclamped( from: Quaternion<T>, to: Quaternion<T>, 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> Mul<T> for Quaternion<T>
impl<T> Mul<T> for Quaternion<T>
§type Output = Quaternion<T>
type Output = Quaternion<T>
*
operator.source§impl<T> Mul<Vec3<T>> for Quaternion<T>
impl<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> Mul<Vec3<T>> for Quaternion<T>
impl<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> Mul<Vec4<T>> for Quaternion<T>
impl<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> Mul<Vec4<T>> for Quaternion<T>
impl<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> Mul for Quaternion<T>
impl<T> Mul for Quaternion<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());
§type Output = Quaternion<T>
type Output = Quaternion<T>
*
operator.source§fn mul(self, rhs: Quaternion<T>) -> <Quaternion<T> as Mul>::Output
fn mul(self, rhs: Quaternion<T>) -> <Quaternion<T> as Mul>::Output
*
operation. Read moresource§impl<T> Neg for Quaternion<T>where
T: Neg<Output = T>,
impl<T> Neg for Quaternion<T>where
T: Neg<Output = T>,
§type Output = Quaternion<T>
type Output = Quaternion<T>
-
operator.source§impl<T> PartialEq for Quaternion<T>where
T: PartialEq,
impl<T> PartialEq for Quaternion<T>where
T: PartialEq,
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 for Quaternion<T>where
T: RelativeEq,
<T as AbsDiffEq>::Epsilon: Copy,
impl<T> RelativeEq for Quaternion<T>where
T: RelativeEq,
<T as AbsDiffEq>::Epsilon: Copy,
source§fn default_max_relative() -> <T as AbsDiffEq>::Epsilon
fn default_max_relative() -> <T as AbsDiffEq>::Epsilon
source§fn relative_eq(
&self,
other: &Quaternion<T>,
epsilon: <T as AbsDiffEq>::Epsilon,
max_relative: <T as AbsDiffEq>::Epsilon,
) -> bool
fn relative_eq( &self, other: &Quaternion<T>, epsilon: <T as AbsDiffEq>::Epsilon, max_relative: <T as AbsDiffEq>::Epsilon, ) -> bool
§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§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
source§impl<'a, T, Factor> Slerp<Factor> for &'a Quaternion<T>
impl<'a, T, Factor> Slerp<Factor> for &'a Quaternion<T>
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn slerp_unclamped(
from: &'a Quaternion<T>,
to: &'a Quaternion<T>,
factor: Factor,
) -> Quaternion<T>
fn slerp_unclamped( from: &'a Quaternion<T>, to: &'a Quaternion<T>, factor: Factor, ) -> Quaternion<T>
factor
to
be between 0 and 1.source§impl<T, Factor> Slerp<Factor> for Quaternion<T>
impl<T, Factor> Slerp<Factor> for Quaternion<T>
§type Output = Quaternion<T>
type Output = Quaternion<T>
source§fn slerp_unclamped(
from: Quaternion<T>,
to: Quaternion<T>,
factor: Factor,
) -> Quaternion<T>
fn slerp_unclamped( from: Quaternion<T>, to: Quaternion<T>, factor: Factor, ) -> Quaternion<T>
factor
to
be between 0 and 1.source§impl<T> Sub for Quaternion<T>where
T: Sub<Output = T>,
impl<T> Sub for Quaternion<T>where
T: Sub<Output = T>,
§type Output = Quaternion<T>
type Output = Quaternion<T>
-
operator.source§fn sub(self, rhs: Quaternion<T>) -> <Quaternion<T> as Sub>::Output
fn sub(self, rhs: Quaternion<T>) -> <Quaternion<T> as Sub>::Output
-
operation. Read moresource§impl<T> UlpsEq for Quaternion<T>where
T: UlpsEq,
<T as AbsDiffEq>::Epsilon: Copy,
impl<T> UlpsEq for Quaternion<T>where
T: UlpsEq,
<T as AbsDiffEq>::Epsilon: Copy,
source§fn default_max_ulps() -> u32
fn default_max_ulps() -> u32
impl<T> Copy for Quaternion<T>where
T: Copy,
impl<T> Eq for Quaternion<T>where
T: Eq,
impl<T> StructuralPartialEq for Quaternion<T>
Auto Trait Implementations§
impl<T> Freeze for Quaternion<T>where
T: Freeze,
impl<T> RefUnwindSafe for Quaternion<T>where
T: RefUnwindSafe,
impl<T> Send for Quaternion<T>where
T: Send,
impl<T> Sync for Quaternion<T>where
T: Sync,
impl<T> Unpin for Quaternion<T>where
T: Unpin,
impl<T> UnwindSafe for Quaternion<T>where
T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§default unsafe fn clone_to_uninit(&self, dst: *mut T)
default unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)source§impl<T> CloneToUninit for Twhere
T: Copy,
impl<T> CloneToUninit for Twhere
T: Copy,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)§impl<C, M> ConvertSaveload<M> for C
impl<C, M> ConvertSaveload<M> for C
§type Error = Infallible
type Error = Infallible
§fn convert_into<F>(
&self,
_: F,
) -> Result<<C as ConvertSaveload<M>>::Data, <C as ConvertSaveload<M>>::Error>
fn convert_into<F>( &self, _: F, ) -> Result<<C as ConvertSaveload<M>>::Data, <C as ConvertSaveload<M>>::Error>
Data
) using
entity to marker mapping function§fn convert_from<F>(
data: <C as ConvertSaveload<M>>::Data,
_: F,
) -> Result<C, <C as ConvertSaveload<M>>::Error>
fn convert_from<F>( data: <C as ConvertSaveload<M>>::Data, _: F, ) -> Result<C, <C as ConvertSaveload<M>>::Error>
Data
) using
entity to marker mapping function§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.§impl<T> GetSetFdFlags for T
impl<T> GetSetFdFlags for T
§fn get_fd_flags(&self) -> Result<FdFlags, Error>where
T: AsFilelike,
fn get_fd_flags(&self) -> Result<FdFlags, Error>where
T: AsFilelike,
self
file descriptor.§fn new_set_fd_flags(&self, fd_flags: FdFlags) -> Result<SetFdFlags<T>, Error>where
T: AsFilelike,
fn new_set_fd_flags(&self, fd_flags: FdFlags) -> Result<SetFdFlags<T>, Error>where
T: AsFilelike,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Pointee for T
impl<T> Pointee for T
§impl<Context> SubContext<Context> for Context
impl<Context> SubContext<Context> for Context
fn sub_context(self) -> Context
§impl<T> TryDefault for Twhere
T: Default,
impl<T> TryDefault for Twhere
T: Default,
§fn try_default() -> Result<T, String>
fn try_default() -> Result<T, String>
§fn unwrap_default() -> Self
fn unwrap_default() -> Self
try_default
and panics on an error case.