pub struct Rotor<const N: usize, T, A: Alignment>(/* private fields */)
where
Dim<N>: Three,
T: Element;Expand description
A rotor representing rotation.
Use vector * rotor to transform vectors.
A rotor is a mathematical object used to represent rotations. You may be familiar with quaternions, which are mathematically identical to 3D rotors, however rotors tend to be easier to understand, and extend better to dimensions other than 3D.
In comparison to rotation matrices, rotors are more compact, are faster to chain, and can be properly interpolated, making them the best type for manipulating rotations. Applying a rotor on a vector is slower than applying a matrix, so consider converting your rotor to a matrix before rotating a lot of vectors.
This rotor is intended to be normalized, but may denormalize due to floating
point “error creep” which can occur when successive operations are applied.
Use rotor.normalize() to maintain precision.
§Type aliases
§Representation
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions. You may find it easier to read documentation specific to 3D first. This section explains the representation in a dimension agnostic manner.
This type stores all multivector elements that have an even grade.
- In 2D, this is:
s, xy - In 3D, this is:
s, xy, xz, yz - In 4D, this is:
s, xy, xz, xw, yz, yw, zw, xyzw
This type uses the rotor convention R = e^(B/2), with vector
multiplication R~vR. This differs from the traditional convention,
R = e^(-B/2) and RvR~.
Note that the order of elements in memory and plane orientations (xy
versus yx) do not necessarily follow lexicographical ordering. They may
vary with N to enable dimension-specific optimizations. Currently, only
3D rotors are supported, and their representation is yz, zx, xy, s rather
than the natural s, xy, xz, yz.
Fields are exposed by implementing Deref and DerefMut.
§Memory layout
Rotor<3, T, A> is a transparent wrapper around Vector<4, T, A>.
If additional dimensions are ever supported, Rotor<N, T, A> would remain
a transparent wrapper around Vector<rotor_len(N), T, A>, where
rotor_len(n) = sum((0..=n).step_by(2).map(|k| (n choose k))).
Implementations§
Source§impl<const N: usize, T, A: Alignment> Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> Rotor<N, T, A>
Sourcepub fn conjugate(self) -> Selfwhere
T: Neg<Output = T>,
pub fn conjugate(self) -> Selfwhere
T: Neg<Output = T>,
Returns the conjugate of a rotor.
This performs the same operation as inverse.
Sourcepub fn length_squared(self) -> T
pub fn length_squared(self) -> T
Computes the squared length/magnitude of a rotor.
Sourcepub const fn align(self) -> Rotor<N, T, Aligned>
pub const fn align(self) -> Rotor<N, T, Aligned>
Converts self to SIMD-aligned storage.
See Alignment for more information about SIMD-aligned types.
Source§impl<T, A: Alignment> Rotor<3, T, A>where
T: Element,
impl<T, A: Alignment> Rotor<3, T, A>where
T: Element,
Sourcepub const fn from_elements(yz: T, zx: T, xy: T, s: T) -> Self
pub const fn from_elements(yz: T, zx: T, xy: T, s: T) -> Self
Creates a 3D rotor from elements yz, zx, xy, s.
Note that a rotor is meant to be normalized, but this function does not enforce that.
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn from_array(array: [T; 4]) -> Self
pub const fn from_array(array: [T; 4]) -> Self
Creates a 3D rotor from an element array [yz, zx, xy, s].
Note that a rotor is meant to be normalized, but this function does not enforce that.
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn to_array(self) -> [T; 4]
pub const fn to_array(self) -> [T; 4]
Converts a 3D rotor to an element array [yz, zx, xy, s].
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn as_array(&self) -> &[T; 4]
pub const fn as_array(&self) -> &[T; 4]
Returns a reference to a 3D rotor element array [yz, zx, xy, s].
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn as_mut_array(&mut self) -> &mut [T; 4]
pub const fn as_mut_array(&mut self) -> &mut [T; 4]
Returns a mutable reference to a 3D rotor element array
[yz, zx, xy, s].
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn from_raw_vector(vector: Vector<4, T, A>) -> Self
pub const fn from_raw_vector(vector: Vector<4, T, A>) -> Self
Creates a 3D rotor from an element vector (yz, zx, xy, s).
Note that a rotor is meant to be normalized, but this function does not enforce that.
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn to_raw_vector(self) -> Vector<4, T, A>
pub const fn to_raw_vector(self) -> Vector<4, T, A>
Converts a 3D rotor to an element vector (yz, zx, xy, s).
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn as_raw_vector(&self) -> &Vector<4, T, A>
pub const fn as_raw_vector(&self) -> &Vector<4, T, A>
Returns a reference to a 3D rotor element vector (yz, zx, xy, s).
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Sourcepub const fn as_mut_raw_vector(&mut self) -> &mut Vector<4, T, A>
pub const fn as_mut_raw_vector(&mut self) -> &mut Vector<4, T, A>
Returns a mutable reference to a 3D rotor element vector
(yz, zx, xy, s).
Unless you are familiar with rotor/quaternion math, avoid using rotor elements directly. Instead, use higher level helper functions.
Source§impl<const N: usize, T, A: Alignment> Rotor<N, T, A>where
Dim<N>: Three,
T: PrimitiveFloat,
impl<const N: usize, T, A: Alignment> Rotor<N, T, A>where
Dim<N>: Three,
T: PrimitiveFloat,
Sourcepub const NAN: Self = Self::NAN_INTERNAL_IMPL
pub const NAN: Self = Self::NAN_INTERNAL_IMPL
A rotor with all elements set to NaN (Not a Number).
Sourcepub fn from_rotation_arc(from: Vector<N, T, A>, to: Vector<N, T, A>) -> Self
pub fn from_rotation_arc(from: Vector<N, T, A>, to: Vector<N, T, A>) -> Self
Returns the minimal rotation transforming from to to.
The rotation is in the plane spanned by from and to. Rotates up to
180 degrees.
When from≈to this is only accurate to about 0.001 (for f32).
This assumes from and to are normalized.
§Panics
When debug assertions are enabled:
Panics if from or to are not normalized.
Sourcepub fn from_rotation_arc_colinear(
from: Vector<N, T, A>,
to: Vector<N, T, A>,
) -> Self
pub fn from_rotation_arc_colinear( from: Vector<N, T, A>, to: Vector<N, T, A>, ) -> Self
Returns the minimal rotation transforming from to either to or
-to. This rotates from so that it is colinear with to.
The rotation is in the plane spanned by from and to. Rotates up to
90 degrees.
When from≈to or from≈-to this is only accurate to about 0.001 (for
f32).
This assumes from and to are normalized.
§Panics
When debug assertions are enabled:
Panics if from or to are not normalized.
Sourcepub fn from_matrix(matrix: &Matrix<N, T, A>) -> Self
pub fn from_matrix(matrix: &Matrix<N, T, A>) -> Self
Converts a matrix to a rotor.
This assumes matrix only contains rotation.
§Panics
When debug assertions are enabled:
Panics if matrix contains anything but rotation.
Sourcepub fn to_matrix(self) -> Matrix<N, T, A>
pub fn to_matrix(self) -> Matrix<N, T, A>
Converts a rotor to a matrix.
This assumes self is normalized.
§Panics
When debug assertions are enabled:
Panics if self is not normalized.
Sourcepub fn from_affine(affine: &Affine<N, T, A>) -> Self
pub fn from_affine(affine: &Affine<N, T, A>) -> Self
Converts an affine transform to a rotor.
This assumes affine only contains rotation, and translation which is
ignored.
§Panics
When debug assertions are enabled:
Panics if affine contains anything but rotation and translation.
Sourcepub fn to_affine(self) -> Affine<N, T, A>
pub fn to_affine(self) -> Affine<N, T, A>
Converts a rotor to an affine transform.
This assumes self is normalized.
§Panics
When debug assertions are enabled:
Panics if self is not normalized.
Sourcepub fn from_projective(projective: &Projective<N, T, A>) -> Self
pub fn from_projective(projective: &Projective<N, T, A>) -> Self
Converts a projective transform to a rotor.
This assumes projective only contains rotation, and translation which
is ignored.
§Panics
When debug assertions are enabled:
Panics if projective contains anything but rotation and translation.
Sourcepub fn to_projective(self) -> Projective<N, T, A>
pub fn to_projective(self) -> Projective<N, T, A>
Converts a rotor to a projective transform.
This assumes self is normalized.
§Panics
When debug assertions are enabled:
Panics if self is not normalized.
Sourcepub fn angle_between(self, other: Self) -> T
pub fn angle_between(self, other: Self) -> T
Returns the angle (in radians) for the minimal rotation for transforming
self into other in the range 0..=+π.
This assumes self and other are normalized.
§Panics
When debug assertions are enabled:
Panics if self or other are not normalized.
Sourcepub fn angle_between_long(self, other: Self) -> T
pub fn angle_between_long(self, other: Self) -> T
Returns the angle (in radians) transforming self into other in the
range 0..2π.
This assumes self and other are normalized.
This function takes advantage of the fact that, for any rotor r, the
rotor -r represents the same rotation. If self.dot(other) is
positive, this takes the shorter rotational path. If self.dot(other)
is negative, this takes the longer rotational path.
§Panics
When debug assertions are enabled:
Panics if self or other are not normalized.
Sourcepub fn lerp(self, other: Self, t: T) -> Self
pub fn lerp(self, other: Self, t: T) -> Self
Computes the linear interpolation between two rotors, then normalizes the result.
When t is 0, the result is self. When t is 1, the result is
other. This always takes the shorter path between the rotations.
This assumes self and other are normalized.
This does not interpolate the angle at a constant speed. For that use
slerp. This function is more efficient as it avoids calling
trigonometric functions.
§Panics
When debug assertions are enabled:
Panics if self or other are not normalized.
Sourcepub fn slerp(self, other: Self, t: T) -> Self
pub fn slerp(self, other: Self, t: T) -> Self
Computes the spherical linear interpolation between two rotors.
When t is 0, the result is self. When t is 1, the result is
other. This interpolates the angle at a constant speed, always taking
the shorter path.
This assumes self and other are normalized.
§Panics
When debug assertions are enabled:
Panics if self or other are not normalized.
Sourcepub fn slerp_long(self, other: Self, t: T) -> Self
pub fn slerp_long(self, other: Self, t: T) -> Self
Computes the spherical linear interpolation between two rotors.
This assumes self and other are normalized.
When t is 0, the result is self. When t is 1, the result is
other. This interpolates the angle at a constant speed.
This function takes advantage of the fact that, for any rotor r, the
rotor -r represents the same rotation. If self.dot(other) is
positive, this takes the shorter rotational path. If self.dot(other)
is negative, this takes the longer rotational path.
§Panics
When debug assertions are enabled:
Panics if self or other are not normalized.
Sourcepub fn rotate_towards(self, target: Self, max_angle: T) -> Self
pub fn rotate_towards(self, target: Self, max_angle: T) -> Self
Rotates one rotor towards another by at most max_angle (in radians).
This assumes self and other are normalized.
When max_angle is 0, the result is self. When max_angle is equal
to or greater than self.angle_between(target), the result is target.
When max_angle is negative, this rotates towards the opposite of
target.
§Panics
When debug assertions are enabled:
Panics if self or other are not normalized.
Sourcepub fn rotate_towards_long(self, target: Self, max_angle: T) -> Self
pub fn rotate_towards_long(self, target: Self, max_angle: T) -> Self
Rotates one rotor towards another by at most max_angle (in radians).
This assumes self and other are normalized, and max_angle is
positive.
When max_angle is 0, the result is self. When max_angle is equal
to or greater than self.angle_between_long(target), the result is
target.
This function takes advantage of the fact that, for any rotor r, the
rotor -r represents the same rotation. If self.dot(other) is
positive, this takes the shorter rotational path. If self.dot(other)
is negative, this takes the longer rotational path.
§Panics
When debug assertions are enabled:
Panics if self or other are not normalized, or if max_angle is
negative.
Sourcepub fn normalize(self) -> Self
pub fn normalize(self) -> Self
Returns self normalized to length 1.
This assumes self is not zero.
§Panics
When debug assertions are enabled:
Panics if self is zero, or if the result is non finite or zero.
Sourcepub fn try_normalize(self) -> Option<Self>
pub fn try_normalize(self) -> Option<Self>
Returns normalize, or None if self is zero or if the result is
non finite or zero.
Sourcepub fn normalize_or(self, fallback: Self) -> Self
pub fn normalize_or(self, fallback: Self) -> Self
Returns normalize, or fallback if self is zero or if the result
is non finite or zero.
Sourcepub fn normalize_and_length(self) -> (Self, T)
pub fn normalize_and_length(self) -> (Self, T)
Sourcepub fn is_normalized(self) -> bool
pub fn is_normalized(self) -> bool
Returns whether a rotor has the length 1 or not.
This uses a precision threshold of approximately 1e-4.
Sourcepub fn abs_diff_eq(self, other: Self, max_abs_diff: T) -> bool
pub fn abs_diff_eq(self, other: Self, max_abs_diff: T) -> bool
Returns true if the absolute difference of all elements between self
and other is less than or equal to max_abs_diff.
This can be used to compare two rotors that should be equal, but may have a slight difference due to operations having rounding errors.
Source§impl<T, A: Alignment> Rotor<3, T, A>where
T: PrimitiveFloat,
impl<T, A: Alignment> Rotor<3, T, A>where
T: PrimitiveFloat,
Sourcepub fn from_rotation_xy(angle: T) -> Self
pub fn from_rotation_xy(angle: T) -> Self
Creates a 3D rotor from an angle (in radians) rotating +X to +Y.
Sourcepub fn from_rotation_xz(angle: T) -> Self
pub fn from_rotation_xz(angle: T) -> Self
Creates a 3D rotor from an angle (in radians) rotating +X to +Z.
Sourcepub fn from_rotation_yz(angle: T) -> Self
pub fn from_rotation_yz(angle: T) -> Self
Creates a 3D rotor from an angle (in radians) rotating +Y to +Z.
Sourcepub fn from_axis_angle(axis: Vector<3, T, A>, angle: T) -> Self
pub fn from_axis_angle(axis: Vector<3, T, A>, angle: T) -> Self
Creates a 3D rotor from a rotation axis and an angle (in radians).
This follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
This assumes axis is normalized.
§Panics
When debug assertions are enabled:
Panics if axis is not normalized.
Sourcepub fn to_axis_angle(self) -> (Vector<3, T, A>, T)
pub fn to_axis_angle(self) -> (Vector<3, T, A>, T)
Converts a 3D rotor to a rotation axis and an angle (in radians).
This follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
This assumes self is normalized.
§Panics
When debug assertions are enabled:
Panics if self is not normalized.
Sourcepub fn from_scaled_axis(scaled_axis: Vector<3, T, A>) -> Self
pub fn from_scaled_axis(scaled_axis: Vector<3, T, A>) -> Self
Creates a 3D rotor from a rotation axis scaled by an angle (in radians).
Equivalent to:
Self::from_axis_angle(
scaled_axis.normalize(),
scaled_axis.length(),
)This follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
Sourcepub fn to_scaled_axis(self) -> Vector<3, T, A>
pub fn to_scaled_axis(self) -> Vector<3, T, A>
Converts a 3D rotor to a rotation axis scaled by an angle (in radians).
Equivalent to:
let (axis, angle) = self.to_axis_angle();
axis * angleThis follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
This assumes self is normalized.
§Panics
When debug assertions are enabled:
Panics if self is not normalized.
Sourcepub fn from_euler(order: EulerRot, a: T, b: T, c: T) -> Self
pub fn from_euler(order: EulerRot, a: T, b: T, c: T) -> Self
Creates a 3D rotor from an Euler rotation order/sequence and angles (in radians).
Sourcepub fn to_euler(self, order: EulerRot) -> (T, T, T)
pub fn to_euler(self, order: EulerRot) -> (T, T, T)
Converts a 3D rotor to Euler angles for a given Euler rotation order/sequence.
This assumes self is normalized.
§Panics
When debug assertions are enabled:
Panics if self is not normalized.
Sourcepub fn look_to_lh(dir: Vector<3, T, A>, up: Vector<3, T, A>) -> Self
pub fn look_to_lh(dir: Vector<3, T, A>, up: Vector<3, T, A>) -> Self
Creates a 3D rotor from a facing direction and an up direction.
For a left-handed view coordinate system with +X=right, +Y=up and
+Z=forward.
§Panics
When debug assertions are enabled:
Panics if:
dirorupare not normalizeddirandupare parallel
Sourcepub fn look_to_rh(dir: Vector<3, T, A>, up: Vector<3, T, A>) -> Self
pub fn look_to_rh(dir: Vector<3, T, A>, up: Vector<3, T, A>) -> Self
Creates a 3D rotor from a facing direction and an up direction.
For a right-handed view coordinate system with +X=right, +Y=up and
+Z=back.
§Panics
When debug assertions are enabled:
Panics if:
dirorupare not normalizeddirandupare parallel
Sourcepub fn look_at_lh(
eye: Vector<3, T, A>,
center: Vector<3, T, A>,
up: Vector<3, T, A>,
) -> Self
pub fn look_at_lh( eye: Vector<3, T, A>, center: Vector<3, T, A>, up: Vector<3, T, A>, ) -> Self
Creates a 3D rotor from a camera position, a focal point and an up direction.
For a left-handed view coordinate system with +X=right, +Y=up and
+Z=forward.
§Panics
When debug assertions are enabled:
Panics if:
upis not normalizedcenteris equal toeye- The resulting forward direction is parallel to
up
Sourcepub fn look_at_rh(
eye: Vector<3, T, A>,
center: Vector<3, T, A>,
up: Vector<3, T, A>,
) -> Self
pub fn look_at_rh( eye: Vector<3, T, A>, center: Vector<3, T, A>, up: Vector<3, T, A>, ) -> Self
Creates a 3D rotor from a camera position, a focal point and an up direction.
For a right-handed view coordinate system with +X=right, +Y=up and
+Z=back.
§Panics
When debug assertions are enabled:
Panics if:
upis not normalizedcenteris equal toeye- The resulting forward direction is parallel to
up
Source§impl<const N: usize, Wide, T, const LANES: usize, A: Alignment> Rotor<N, Wide, A>
Functionality for SoA (Structure of Arrays) rotors.
impl<const N: usize, Wide, T, const LANES: usize, A: Alignment> Rotor<N, Wide, A>
Functionality for SoA (Structure of Arrays) rotors.
This is gated behind the wide feature flag.
This functionality is shown with generics to make it easier to read. This
works with all types from the wide crate.
Sourcepub fn from_lanes(lanes: &[Rotor<N, T, A>; LANES]) -> Self
pub fn from_lanes(lanes: &[Rotor<N, T, A>; LANES]) -> Self
Creates an SoA (Structure of Arrays) rotor from an array of regular, non-SoA rotors corresponding to each output lane.
§Examples
let lanes = [
Rotor3::from_elements(1, 2, 3, 4),
Rotor3::from_elements(11, 12, 13, 14),
Rotor3::from_elements(21, 22, 23, 24),
Rotor3::from_elements(31, 32, 33, 34),
];
assert_eq!(
Rotor3::<i32x4>::from_lanes(&lanes),
Rotor3::from_elements(
i32x4::new([1, 11, 21, 31]),
i32x4::new([2, 12, 22, 32]),
i32x4::new([3, 13, 23, 33]),
i32x4::new([4, 14, 24, 34]),
),
);Sourcepub fn to_lanes(&self) -> [Rotor<N, T, A>; LANES]
pub fn to_lanes(&self) -> [Rotor<N, T, A>; LANES]
Converts an SoA (Structure of Arrays) rotor to an array of regular, non-SoA rotors corresponding to each input lane.
§Examples
let soa = Rotor3::from_elements(
i32x4::new([1, 11, 21, 31]),
i32x4::new([2, 12, 22, 32]),
i32x4::new([3, 13, 23, 33]),
i32x4::new([4, 14, 24, 34]),
);
assert_eq!(
soa.to_lanes(),
[
Rotor3::from_elements(1, 2, 3, 4),
Rotor3::from_elements(11, 12, 13, 14),
Rotor3::from_elements(21, 22, 23, 24),
Rotor3::from_elements(31, 32, 33, 34),
],
);Sourcepub fn from_lane_fn<F>(f: F) -> Self
pub fn from_lane_fn<F>(f: F) -> Self
Creates an SoA (Structure of Arrays) rotor by calling function f for
each output lane.
§Examples
let lanes = [
Rotor3::from_elements(1, 2, 3, 4),
Rotor3::from_elements(11, 12, 13, 14),
Rotor3::from_elements(21, 22, 23, 24),
Rotor3::from_elements(31, 32, 33, 34),
];
assert_eq!(
Rotor3::<i32x4>::from_lane_fn(|lane_index| lanes[lane_index]),
Rotor3::from_elements(
i32x4::new([1, 11, 21, 31]),
i32x4::new([2, 12, 22, 32]),
i32x4::new([3, 13, 23, 33]),
i32x4::new([4, 14, 24, 34]),
),
);Sourcepub fn lane(&self, lane: usize) -> Rotor<N, T, A>
pub fn lane(&self, lane: usize) -> Rotor<N, T, A>
Takes an SoA (Structure of Arrays) rotor transform and returns the lane at the given index.
§Panics
Panics if lane is greater than or equal to the number of lanes.
§Examples
let soa = Rotor3::from_elements(
i32x4::new([1, 11, 21, 31]),
i32x4::new([2, 12, 22, 32]),
i32x4::new([3, 13, 23, 33]),
i32x4::new([4, 14, 24, 34]),
);
assert_eq!(
soa.lane(1),
Rotor3::from_elements(11, 12, 13, 14),
);Sourcepub fn set_lane(&mut self, lane: usize, value: Rotor<N, T, A>)
pub fn set_lane(&mut self, lane: usize, value: Rotor<N, T, A>)
Takes an SoA (Structure of Arrays) rotor and sets the lane at the given
index to value.
§Panics
Panics if lane is greater than or equal to the number of
lanes.
§Examples
let mut soa = Rotor3::from_elements(
i32x4::new([1, 11, 21, 31]),
i32x4::new([2, 12, 22, 32]),
i32x4::new([3, 13, 23, 33]),
i32x4::new([4, 14, 24, 34]),
);
soa.set_lane(1, Rotor3::IDENTITY);
assert_eq!(
soa,
Rotor3::from_elements(
i32x4::new([1, 0, 21, 31]),
i32x4::new([2, 0, 22, 32]),
i32x4::new([3, 0, 23, 33]),
i32x4::new([4, 1, 24, 34]),
),
);Source§impl<const N: usize, Wide, A: Alignment> Rotor<N, Wide, A>where
Dim<N>: Three,
Wide: WideFloat,
Functionality for SoA (Structure of Arrays) float rotors.
impl<const N: usize, Wide, A: Alignment> Rotor<N, Wide, A>where
Dim<N>: Three,
Wide: WideFloat,
Functionality for SoA (Structure of Arrays) float rotors.
This is gated behind the wide feature flag.
This functionality is shown with generics to make it easier to read. This
works with all float types from the wide crate.
Sourcepub const NAN: Self = Self::NAN_INTERNAL_IMPL
pub const NAN: Self = Self::NAN_INTERNAL_IMPL
A rotor with all elements set to NaN (Not a Number).
Sourcepub fn from_rotation_arc(
from: Vector<N, Wide, A>,
to: Vector<N, Wide, A>,
) -> Self
pub fn from_rotation_arc( from: Vector<N, Wide, A>, to: Vector<N, Wide, A>, ) -> Self
Returns the minimal rotation transforming from to to.
The rotation is in the plane spanned by from and to. Rotates up
to 180 degrees.
When from≈to this is only accurate to about 0.001 (for f32).
This assumes from and to are normalized.
Sourcepub fn from_rotation_arc_colinear(
from: Vector<N, Wide, A>,
to: Vector<N, Wide, A>,
) -> Self
pub fn from_rotation_arc_colinear( from: Vector<N, Wide, A>, to: Vector<N, Wide, A>, ) -> Self
Returns the minimal rotation transforming from to either to or
-to. This rotates from so that it is colinear with to.
The rotation is in the plane spanned by from and to. Rotates up
to 90 degrees.
When from≈to or from≈-to this is only accurate to about 0.001
(for f32).
This assumes from and to are normalized.
Sourcepub fn from_matrix(matrix: &Matrix<N, Wide, A>) -> Self
pub fn from_matrix(matrix: &Matrix<N, Wide, A>) -> Self
Converts a matrix to a rotor.
This assumes matrix only contains rotation.
Sourcepub fn to_matrix(self) -> Matrix<N, Wide, A>
pub fn to_matrix(self) -> Matrix<N, Wide, A>
Converts a rotor to a matrix.
This assumes self is normalized.
Sourcepub fn from_affine(affine: &Affine<N, Wide, A>) -> Self
pub fn from_affine(affine: &Affine<N, Wide, A>) -> Self
Converts an affine transform to a rotor.
This assumes affine only contains rotation, and translation which
is ignored.
Sourcepub fn to_affine(self) -> Affine<N, Wide, A>
pub fn to_affine(self) -> Affine<N, Wide, A>
Converts a rotor to an affine transform.
This assumes self is normalized.
Sourcepub fn from_projective(projective: &Projective<N, Wide, A>) -> Self
pub fn from_projective(projective: &Projective<N, Wide, A>) -> Self
Converts a projective transform to a rotor.
This assumes projective only contains rotation, and translation
which is ignored.
Sourcepub fn to_projective(self) -> Projective<N, Wide, A>
pub fn to_projective(self) -> Projective<N, Wide, A>
Converts a rotor to a projective transform.
This assumes self is normalized.
Sourcepub fn angle_between(self, other: Self) -> Wide
pub fn angle_between(self, other: Self) -> Wide
Returns the angle (in radians) for the minimal rotation for
transforming self into other in the range 0..=+π.
This assumes self and other are normalized.
Sourcepub fn angle_between_long(self, other: Self) -> Wide
pub fn angle_between_long(self, other: Self) -> Wide
Returns the angle (in radians) transforming self into other in
the range 0..2π.
This assumes self and other are normalized.
This function takes advantage of the fact that, for any rotor r,
the rotor -r represents the same rotation. If self.dot(other) is
positive, this takes the shorter rotational path. If
self.dot(other) is negative, this takes the longer rotational
path.
Sourcepub fn lerp(self, other: Self, t: Wide) -> Self
pub fn lerp(self, other: Self, t: Wide) -> Self
Computes the linear interpolation between two rotors, then normalizes the result.
When t is 0, the result is self. When t is 1, the result is
other. This always takes the shorter path between the rotations.
This assumes self and other are normalized.
This does not interpolate the angle at a constant speed. For that use
slerp. This function is more efficient as it avoids calling
trigonometric functions.
Sourcepub fn slerp(self, other: Self, t: Wide) -> Self
pub fn slerp(self, other: Self, t: Wide) -> Self
Computes the spherical linear interpolation between two rotors.
When t is 0, the result is self. When t is 1, the result
is other. This interpolates the angle at a constant speed, always
taking the shorter path.
This assumes self and other are normalized.
Sourcepub fn slerp_long(self, other: Self, t: Wide) -> Self
pub fn slerp_long(self, other: Self, t: Wide) -> Self
Computes the spherical linear interpolation between two rotors.
This assumes self and other are normalized.
When t is 0, the result is self. When t is 1, the result
is other. This interpolates the angle at a constant speed.
This function takes advantage of the fact that, for any rotor r,
the rotor -r represents the same rotation. If self.dot(other) is
positive, this takes the shorter rotational path. If
self.dot(other) is negative, this takes the longer rotational
path.
Sourcepub fn rotate_towards(self, target: Self, max_angle: Wide) -> Self
pub fn rotate_towards(self, target: Self, max_angle: Wide) -> Self
Rotates one rotor towards another by at most max_angle (in
radians).
This assumes self and other are normalized.
When max_angle is 0, the result is self. When max_angle is equal
to or greater than self.angle_between(target), the result is target.
When max_angle is negative, this rotates towards the opposite of
target.
Sourcepub fn rotate_towards_long(self, target: Self, max_angle: Wide) -> Self
pub fn rotate_towards_long(self, target: Self, max_angle: Wide) -> Self
Rotates one rotor towards another by at most max_angle (in
radians).
This assumes self and other are normalized, and max_angle
is positive.
When max_angle is 0, the result is self. When max_angle is
equal to or greater than self.angle_between_long(target), the
result is target.
This function takes advantage of the fact that, for any rotor r,
the rotor -r represents the same rotation. If self.dot(other) is
positive, this takes the shorter rotational path. If
self.dot(other) is negative, this takes the longer rotational
path.
Sourcepub fn normalize(self) -> Self
pub fn normalize(self) -> Self
Returns self normalized to length 1.
This assumes self is not zero.
Sourcepub fn normalize_or(self, fallback: Self) -> Self
pub fn normalize_or(self, fallback: Self) -> Self
Returns normalize, or fallback if self is zero or if the
result is non finite or zero.
Sourcepub fn normalize_and_length(self) -> (Self, Wide)
pub fn normalize_and_length(self) -> (Self, Wide)
Sourcepub fn is_normalized(self) -> Wide
pub fn is_normalized(self) -> Wide
Returns whether the rotor has the length 1 or not.
This uses a precision threshold of approximately 1e-4.
Sourcepub fn abs_diff_eq(self, other: Self, max_abs_diff: Wide) -> bool
pub fn abs_diff_eq(self, other: Self, max_abs_diff: Wide) -> bool
Returns true if the absolute difference of all elements between
self and other is less than or equal to max_abs_diff.
This can be used to compare two rotors that should be equal, but may have a slight difference due to operations having rounding errors.
Source§impl<Wide, A: Alignment> Rotor<3, Wide, A>where
Wide: WideFloat,
Functionality for SoA (Structure of Arrays) float 3D rotors.
impl<Wide, A: Alignment> Rotor<3, Wide, A>where
Wide: WideFloat,
Functionality for SoA (Structure of Arrays) float 3D rotors.
This is gated behind the wide feature flag.
This functionality is shown with generics to make it easier to read. This
works with all float types from the wide crate.
Sourcepub fn from_rotation_xy(angle: Wide) -> Self
pub fn from_rotation_xy(angle: Wide) -> Self
Creates a 3D rotor from an angle (in radians) rotating +X to +Y.
Sourcepub fn from_rotation_xz(angle: Wide) -> Self
pub fn from_rotation_xz(angle: Wide) -> Self
Creates a 3D rotor from an angle (in radians) rotating +X to +Z.
Sourcepub fn from_rotation_yz(angle: Wide) -> Self
pub fn from_rotation_yz(angle: Wide) -> Self
Creates a 3D rotor from an angle (in radians) rotating +Y to +Z.
Sourcepub fn from_axis_angle(axis: Vector<3, Wide, A>, angle: Wide) -> Self
pub fn from_axis_angle(axis: Vector<3, Wide, A>, angle: Wide) -> Self
Creates a 3D rotor from a rotation axis and an angle (in radians).
This follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
This assumes axis is normalized.
Sourcepub fn to_axis_angle(self) -> (Vector<3, Wide, A>, Wide)
pub fn to_axis_angle(self) -> (Vector<3, Wide, A>, Wide)
Converts a 3D rotor to a rotation axis and an angle (in radians).
This follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
This assumes self is normalized.
Sourcepub fn from_scaled_axis(scaled_axis: Vector<3, Wide, A>) -> Self
pub fn from_scaled_axis(scaled_axis: Vector<3, Wide, A>) -> Self
Creates a 3D rotor from a rotation axis scaled by an angle (in radians).
Equivalent to:
Self::from_axis_angle(
scaled_axis.normalize(),
scaled_axis.length(),
)This follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
Sourcepub fn to_scaled_axis(self) -> Vector<3, Wide, A>
pub fn to_scaled_axis(self) -> Vector<3, Wide, A>
Converts a 3D rotor to a rotation axis scaled by an angle (in radians).
Equivalent to:
let (axis, angle) = self.to_axis_angle();
axis * angleThis follows the right-hand rule:
+Xrotates+Yto+Z+Yrotates+Zto+X+Zrotates+Xto+Y
This assumes self is normalized.
Sourcepub fn from_euler(order: EulerRot, a: Wide, b: Wide, c: Wide) -> Self
pub fn from_euler(order: EulerRot, a: Wide, b: Wide, c: Wide) -> Self
Creates a 3D rotor from an Euler rotation order/sequence and angles (in radians).
Sourcepub fn to_euler(self, order: EulerRot) -> (Wide, Wide, Wide)
pub fn to_euler(self, order: EulerRot) -> (Wide, Wide, Wide)
Converts a 3D rotor to Euler angles for a given Euler rotation order/sequence.
This assumes self is normalized.
Sourcepub fn look_to_lh(dir: Vector<3, Wide, A>, up: Vector<3, Wide, A>) -> Self
pub fn look_to_lh(dir: Vector<3, Wide, A>, up: Vector<3, Wide, A>) -> Self
Creates a 3D rotor from a facing direction and an up direction.
For a left-handed view coordinate system with +X=right, +Y=up
and +Z=forward.
Sourcepub fn look_to_rh(dir: Vector<3, Wide, A>, up: Vector<3, Wide, A>) -> Self
pub fn look_to_rh(dir: Vector<3, Wide, A>, up: Vector<3, Wide, A>) -> Self
Creates a 3D rotor from a facing direction and an up direction.
For a right-handed view coordinate system with +X=right, +Y=up
and +Z=back.
Sourcepub fn look_at_lh(
eye: Vector<3, Wide, A>,
center: Vector<3, Wide, A>,
up: Vector<3, Wide, A>,
) -> Self
pub fn look_at_lh( eye: Vector<3, Wide, A>, center: Vector<3, Wide, A>, up: Vector<3, Wide, A>, ) -> Self
Creates a 3D rotor from a camera position, a focal point and an up direction.
For a left-handed view coordinate system with +X=right, +Y=up
and +Z=forward.
Sourcepub fn look_at_rh(
eye: Vector<3, Wide, A>,
center: Vector<3, Wide, A>,
up: Vector<3, Wide, A>,
) -> Self
pub fn look_at_rh( eye: Vector<3, Wide, A>, center: Vector<3, Wide, A>, up: Vector<3, Wide, A>, ) -> Self
Creates a 3D rotor from a camera position, a focal point and an up direction.
For a right-handed view coordinate system with +X=right, +Y=up
and +Z=back.
Trait Implementations§
Source§impl<const N: usize, T, A: Alignment> Add for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> Add for Rotor<N, T, A>
Source§impl<const N: usize, T, A: Alignment> Add for &Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> Add for &Rotor<N, T, A>
Source§impl<const N: usize, T, A: Alignment> Add<&Rotor<N, T, A>> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> Add<&Rotor<N, T, A>> for Rotor<N, T, A>
Source§impl<const N: usize, T, A: Alignment> Add<Rotor<N, T, A>> for &Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> Add<Rotor<N, T, A>> for &Rotor<N, T, A>
Source§impl<const N: usize, T, A: Alignment> AddAssign for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> AddAssign for Rotor<N, T, A>
Source§fn add_assign(&mut self, rhs: Self)
fn add_assign(&mut self, rhs: Self)
Adds the elements of two rotors.
This usually does not result in a valid rotation. Only use this if you
know what you are doing! To chain two rotations, use
rotor_1 * rotor_2.
Source§impl<const N: usize, T, A: Alignment> AddAssign<&Rotor<N, T, A>> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> AddAssign<&Rotor<N, T, A>> for Rotor<N, T, A>
Source§fn add_assign(&mut self, rhs: &Self)
fn add_assign(&mut self, rhs: &Self)
Adds the elements of two rotors.
This usually does not result in a valid rotation. Only use this if you
know what you are doing! To chain two rotations, use
rotor_1 * rotor_2.
impl<const N: usize, T, A: Alignment> Copy for Rotor<N, T, A>
Source§impl<const N: usize, T, A: Alignment> DivAssign<&T> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> DivAssign<&T> for Rotor<N, T, A>
Source§fn div_assign(&mut self, rhs: &T)
fn div_assign(&mut self, rhs: &T)
Divides the elements of a rotor by a scalar.
This usually does not result in a valid rotation. Only use this if you know what you are doing!
Source§impl<const N: usize, T, A: Alignment> DivAssign<T> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> DivAssign<T> for Rotor<N, T, A>
Source§fn div_assign(&mut self, rhs: T)
fn div_assign(&mut self, rhs: T)
Divides the elements of a rotor by a scalar.
This usually does not result in a valid rotation. Only use this if you know what you are doing!
impl<const N: usize, T, A: Alignment> Eq for Rotor<N, T, A>
Source§impl<const N: usize, T, A: Alignment> MulAssign for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> MulAssign for Rotor<N, T, A>
Source§fn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
Multiplies two rotors, returning a rotor equivalent to applying the left rotor then the right rotor.
Source§impl<const N: usize, T, A: Alignment> MulAssign<&Rotor<N, T, A>> for Vector<N, T, A>
impl<const N: usize, T, A: Alignment> MulAssign<&Rotor<N, T, A>> for Vector<N, T, A>
Source§fn mul_assign(&mut self, rhs: &Rotor<N, T, A>)
fn mul_assign(&mut self, rhs: &Rotor<N, T, A>)
Transforms a vector by a rotor.
If the rotor is not normalized, this scales the vector by the rotor’s squared length.
Source§impl<const N: usize, T, A: Alignment> MulAssign<&Rotor<N, T, A>> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> MulAssign<&Rotor<N, T, A>> for Rotor<N, T, A>
Source§fn mul_assign(&mut self, rhs: &Rotor<N, T, A>)
fn mul_assign(&mut self, rhs: &Rotor<N, T, A>)
Multiplies two rotors, returning a rotor equivalent to applying the left rotor then the right rotor.
Source§impl<const N: usize, T, A: Alignment> MulAssign<&T> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> MulAssign<&T> for Rotor<N, T, A>
Source§fn mul_assign(&mut self, rhs: &T)
fn mul_assign(&mut self, rhs: &T)
Multiplies the elements of a rotor by a scalar.
This usually does not result in a valid rotation. Only use this if you know what you are doing!
Source§impl<const N: usize, T, A: Alignment> MulAssign<Rotor<N, T, A>> for Vector<N, T, A>
impl<const N: usize, T, A: Alignment> MulAssign<Rotor<N, T, A>> for Vector<N, T, A>
Source§fn mul_assign(&mut self, rhs: Rotor<N, T, A>)
fn mul_assign(&mut self, rhs: Rotor<N, T, A>)
Transforms a vector by a rotor.
If the rotor is not normalized, this scales the vector by the rotor’s squared length.
Source§impl<const N: usize, T, A: Alignment> MulAssign<T> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> MulAssign<T> for Rotor<N, T, A>
Source§fn mul_assign(&mut self, rhs: T)
fn mul_assign(&mut self, rhs: T)
Multiplies the elements of a rotor by a scalar.
This usually does not result in a valid rotation. Only use this if you know what you are doing!
impl<const N: usize, T, A: Alignment> RefUnwindSafe for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> Send for Rotor<N, T, A>
Source§impl<const N: usize, T, A: Alignment> SubAssign for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> SubAssign for Rotor<N, T, A>
Source§fn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
Subtracts the elements of two rotors.
This usually does not result in a valid rotation. Only use this if you know what you are doing!
Source§impl<const N: usize, T, A: Alignment> SubAssign<&Rotor<N, T, A>> for Rotor<N, T, A>
impl<const N: usize, T, A: Alignment> SubAssign<&Rotor<N, T, A>> for Rotor<N, T, A>
Source§fn sub_assign(&mut self, rhs: &Self)
fn sub_assign(&mut self, rhs: &Self)
Subtracts the elements of two rotors.
This usually does not result in a valid rotation. Only use this if you know what you are doing!