Add missing docs.
This commit is contained in:
parent
c5dad7f960
commit
2c03353b30
|
@ -256,7 +256,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
|
||||||
/// Sets the magnitude of this vector.
|
/// Sets the magnitude of this vector.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_magnitude(&mut self, magnitude: N::SimdRealField)
|
pub fn set_magnitude(&mut self, magnitude: N::SimdRealField)
|
||||||
where S: StorageMut<N, R, C> {
|
where
|
||||||
|
S: StorageMut<N, R, C>,
|
||||||
|
{
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
self.scale_mut(magnitude / n)
|
self.scale_mut(magnitude / n)
|
||||||
}
|
}
|
||||||
|
@ -265,7 +267,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use normalize_mut()?"]
|
#[must_use = "Did you mean to use normalize_mut()?"]
|
||||||
pub fn normalize(&self) -> MatrixMN<N, R, C>
|
pub fn normalize(&self) -> MatrixMN<N, R, C>
|
||||||
where DefaultAllocator: Allocator<N, R, C> {
|
where
|
||||||
|
DefaultAllocator: Allocator<N, R, C>,
|
||||||
|
{
|
||||||
self.unscale(self.norm())
|
self.unscale(self.norm())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,6 +279,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S
|
||||||
self.apply_norm(&LpNorm(p))
|
self.apply_norm(&LpNorm(p))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempts to normalize `self`.
|
||||||
|
///
|
||||||
|
/// The components of this matrix can be SIMD types.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use simd_try_normalize_mut()?"]
|
#[must_use = "Did you mean to use simd_try_normalize_mut()?"]
|
||||||
pub fn simd_try_normalize(&self, min_norm: N::SimdRealField) -> SimdOption<MatrixMN<N, R, C>>
|
pub fn simd_try_normalize(&self, min_norm: N::SimdRealField) -> SimdOption<MatrixMN<N, R, C>>
|
||||||
|
@ -296,7 +303,9 @@ impl<N: ComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||||
/// Otherwise this is equivalent to: `*self = self.normalize() * magnitude.
|
/// Otherwise this is equivalent to: `*self = self.normalize() * magnitude.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_set_magnitude(&mut self, magnitude: N::RealField, min_magnitude: N::RealField)
|
pub fn try_set_magnitude(&mut self, magnitude: N::RealField, min_magnitude: N::RealField)
|
||||||
where S: StorageMut<N, R, C> {
|
where
|
||||||
|
S: StorageMut<N, R, C>,
|
||||||
|
{
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
|
|
||||||
if n >= min_magnitude {
|
if n >= min_magnitude {
|
||||||
|
@ -305,10 +314,14 @@ impl<N: ComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a normalized version of this matrix unless its norm as smaller or equal to `eps`.
|
/// Returns a normalized version of this matrix unless its norm as smaller or equal to `eps`.
|
||||||
|
///
|
||||||
|
/// The components of this matrix cannot be SIMD types (see `simd_try_normalize`) instead.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use try_normalize_mut()?"]
|
#[must_use = "Did you mean to use try_normalize_mut()?"]
|
||||||
pub fn try_normalize(&self, min_norm: N::RealField) -> Option<MatrixMN<N, R, C>>
|
pub fn try_normalize(&self, min_norm: N::RealField) -> Option<MatrixMN<N, R, C>>
|
||||||
where DefaultAllocator: Allocator<N, R, C> {
|
where
|
||||||
|
DefaultAllocator: Allocator<N, R, C>,
|
||||||
|
{
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
|
|
||||||
if n <= min_norm {
|
if n <= min_norm {
|
||||||
|
@ -321,6 +334,8 @@ impl<N: ComplexField, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
|
||||||
|
|
||||||
impl<N: SimdComplexField, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
|
impl<N: SimdComplexField, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S> {
|
||||||
/// Normalizes this matrix in-place and returns its norm.
|
/// Normalizes this matrix in-place and returns its norm.
|
||||||
|
///
|
||||||
|
/// The components of the matrix cannot be SIMD types (see `simd_try_normalize_mut` instead).
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn normalize_mut(&mut self) -> N::SimdRealField {
|
pub fn normalize_mut(&mut self) -> N::SimdRealField {
|
||||||
let n = self.norm();
|
let n = self.norm();
|
||||||
|
@ -329,6 +344,9 @@ impl<N: SimdComplexField, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Normalizes this matrix in-place and return its norm.
|
||||||
|
///
|
||||||
|
/// The components of the matrix can be SIMD types.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use simd_try_normalize_mut()?"]
|
#[must_use = "Did you mean to use simd_try_normalize_mut()?"]
|
||||||
pub fn simd_try_normalize_mut(
|
pub fn simd_try_normalize_mut(
|
||||||
|
@ -364,7 +382,8 @@ impl<N: ComplexField, R: Dim, C: Dim, S: StorageMut<N, R, C>> Matrix<N, R, C, S>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdComplexField, R: Dim, C: Dim> Normed for MatrixMN<N, R, C>
|
impl<N: SimdComplexField, R: Dim, C: Dim> Normed for MatrixMN<N, R, C>
|
||||||
where DefaultAllocator: Allocator<N, R, C>
|
where
|
||||||
|
DefaultAllocator: Allocator<N, R, C>,
|
||||||
{
|
{
|
||||||
type Norm = N::SimdRealField;
|
type Norm = N::SimdRealField;
|
||||||
|
|
||||||
|
@ -390,7 +409,8 @@ where DefaultAllocator: Allocator<N, R, C>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: Scalar + ClosedNeg, R: Dim, C: Dim> Neg for Unit<MatrixMN<N, R, C>>
|
impl<N: Scalar + ClosedNeg, R: Dim, C: Dim> Neg for Unit<MatrixMN<N, R, C>>
|
||||||
where DefaultAllocator: Allocator<N, R, C>
|
where
|
||||||
|
DefaultAllocator: Allocator<N, R, C>,
|
||||||
{
|
{
|
||||||
type Output = Unit<MatrixMN<N, R, C>>;
|
type Output = Unit<MatrixMN<N, R, C>>;
|
||||||
|
|
||||||
|
@ -405,7 +425,8 @@ where DefaultAllocator: Allocator<N, R, C>
|
||||||
// − use `x()` instead of `::canonical_basis_element`
|
// − use `x()` instead of `::canonical_basis_element`
|
||||||
// − use `::new(x, y, z)` instead of `::from_slice`
|
// − use `::new(x, y, z)` instead of `::from_slice`
|
||||||
impl<N: ComplexField, D: DimName> VectorN<N, D>
|
impl<N: ComplexField, D: DimName> VectorN<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D>
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>,
|
||||||
{
|
{
|
||||||
/// The i-the canonical basis element.
|
/// The i-the canonical basis element.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -458,7 +479,9 @@ where DefaultAllocator: Allocator<N, D>
|
||||||
// FIXME: return an iterator instead when `-> impl Iterator` will be supported by Rust.
|
// FIXME: return an iterator instead when `-> impl Iterator` will be supported by Rust.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn orthonormal_subspace_basis<F>(vs: &[Self], mut f: F)
|
pub fn orthonormal_subspace_basis<F>(vs: &[Self], mut f: F)
|
||||||
where F: FnMut(&Self) -> bool {
|
where
|
||||||
|
F: FnMut(&Self) -> bool,
|
||||||
|
{
|
||||||
// FIXME: is this necessary?
|
// FIXME: is this necessary?
|
||||||
assert!(
|
assert!(
|
||||||
vs.len() <= D::dim(),
|
vs.len() <= D::dim(),
|
||||||
|
|
|
@ -25,7 +25,9 @@ pub struct Unit<T> {
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<T: Serialize> Serialize for Unit<T> {
|
impl<T: Serialize> Serialize for Unit<T> {
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer {
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
self.value.serialize(serializer)
|
self.value.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +35,9 @@ impl<T: Serialize> Serialize for Unit<T> {
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Unit<T> {
|
impl<'de, T: Deserialize<'de>> Deserialize<'de> for Unit<T> {
|
||||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||||
where D: Deserializer<'de> {
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
T::deserialize(deserializer).map(|x| Unit { value: x })
|
T::deserialize(deserializer).map(|x| Unit { value: x })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,11 +57,17 @@ impl<T: Abomonation> Abomonation for Unit<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait implemented by entities scan be be normalized and put in an `Unit` struct.
|
||||||
pub trait Normed {
|
pub trait Normed {
|
||||||
|
/// The type of the norm.
|
||||||
type Norm: SimdRealField;
|
type Norm: SimdRealField;
|
||||||
|
/// Computes the norm.
|
||||||
fn norm(&self) -> Self::Norm;
|
fn norm(&self) -> Self::Norm;
|
||||||
|
/// Computes the squared norm.
|
||||||
fn norm_squared(&self) -> Self::Norm;
|
fn norm_squared(&self) -> Self::Norm;
|
||||||
|
/// Multiply `self` by n.
|
||||||
fn scale_mut(&mut self, n: Self::Norm);
|
fn scale_mut(&mut self, n: Self::Norm);
|
||||||
|
/// Divides `self` by n.
|
||||||
fn unscale_mut(&mut self, n: Self::Norm);
|
fn unscale_mut(&mut self, n: Self::Norm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +83,9 @@ impl<T: Normed> Unit<T> {
|
||||||
/// Returns `None` if the norm was smaller or equal to `min_norm`.
|
/// Returns `None` if the norm was smaller or equal to `min_norm`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_new(value: T, min_norm: T::Norm) -> Option<Self>
|
pub fn try_new(value: T, min_norm: T::Norm) -> Option<Self>
|
||||||
where T::Norm: RealField {
|
where
|
||||||
|
T::Norm: RealField,
|
||||||
|
{
|
||||||
Self::try_new_and_get(value, min_norm).map(|res| res.0)
|
Self::try_new_and_get(value, min_norm).map(|res| res.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +102,9 @@ impl<T: Normed> Unit<T> {
|
||||||
/// Returns `None` if the norm was smaller or equal to `min_norm`.
|
/// Returns `None` if the norm was smaller or equal to `min_norm`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_new_and_get(mut value: T, min_norm: T::Norm) -> Option<(Self, T::Norm)>
|
pub fn try_new_and_get(mut value: T, min_norm: T::Norm) -> Option<(Self, T::Norm)>
|
||||||
where T::Norm: RealField {
|
where
|
||||||
|
T::Norm: RealField,
|
||||||
|
{
|
||||||
let sq_norm = value.norm_squared();
|
let sq_norm = value.norm_squared();
|
||||||
|
|
||||||
if sq_norm > min_norm * min_norm {
|
if sq_norm > min_norm * min_norm {
|
||||||
|
|
|
@ -4,18 +4,30 @@ use crate::{DefaultAllocator, DimName, Point, Scalar, SimdRealField, VectorN, U2
|
||||||
|
|
||||||
use simba::scalar::ClosedMul;
|
use simba::scalar::ClosedMul;
|
||||||
|
|
||||||
|
/// Trait implemented by rotations that can be used inside of an `Isometry` or `Similarity`.
|
||||||
pub trait AbstractRotation<N: Scalar, D: DimName>: PartialEq + ClosedMul + Clone {
|
pub trait AbstractRotation<N: Scalar, D: DimName>: PartialEq + ClosedMul + Clone {
|
||||||
|
/// The rotation identity.
|
||||||
fn identity() -> Self;
|
fn identity() -> Self;
|
||||||
|
/// The rotation inverse.
|
||||||
fn inverse(&self) -> Self;
|
fn inverse(&self) -> Self;
|
||||||
|
/// Change `self` to its inverse.
|
||||||
fn inverse_mut(&mut self);
|
fn inverse_mut(&mut self);
|
||||||
|
/// Apply the rotation to the given vector.
|
||||||
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D>;
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>;
|
||||||
|
/// Apply the rotation to the given point.
|
||||||
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D>;
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>;
|
||||||
|
/// Apply the inverse rotation to the given vector.
|
||||||
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D>;
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>;
|
||||||
|
/// Apply the inverse rotation to the given point.
|
||||||
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D>;
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField, D: DimName> AbstractRotation<N, D> for Rotation<N, D>
|
impl<N: SimdRealField, D: DimName> AbstractRotation<N, D> for Rotation<N, D>
|
||||||
|
@ -40,31 +52,40 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>,
|
||||||
|
{
|
||||||
self * v
|
self * v
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>,
|
||||||
|
{
|
||||||
self * p
|
self * p
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
fn inverse_transform_vector(&self, v: &VectorN<N, D>) -> VectorN<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>,
|
||||||
|
{
|
||||||
self.inverse_transform_vector(v)
|
self.inverse_transform_vector(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
fn inverse_transform_point(&self, p: &Point<N, D>) -> Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>,
|
||||||
|
{
|
||||||
self.inverse_transform_point(p)
|
self.inverse_transform_point(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> AbstractRotation<N, U3> for UnitQuaternion<N>
|
impl<N: SimdRealField> AbstractRotation<N, U3> for UnitQuaternion<N>
|
||||||
where N::Element: SimdRealField
|
where
|
||||||
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Self {
|
fn identity() -> Self {
|
||||||
|
@ -103,7 +124,8 @@ where N::Element: SimdRealField
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> AbstractRotation<N, U2> for UnitComplex<N>
|
impl<N: SimdRealField> AbstractRotation<N, U2> for UnitComplex<N>
|
||||||
where N::Element: SimdRealField
|
where
|
||||||
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn identity() -> Self {
|
fn identity() -> Self {
|
||||||
|
|
|
@ -35,7 +35,8 @@ pub struct Quaternion<N: Scalar + SimdValue> {
|
||||||
|
|
||||||
#[cfg(feature = "abomonation-serialize")]
|
#[cfg(feature = "abomonation-serialize")]
|
||||||
impl<N: SimdRealField> Abomonation for Quaternion<N>
|
impl<N: SimdRealField> Abomonation for Quaternion<N>
|
||||||
where Vector4<N>: Abomonation
|
where
|
||||||
|
Vector4<N>: Abomonation,
|
||||||
{
|
{
|
||||||
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
unsafe fn entomb<W: Write>(&self, writer: &mut W) -> IOResult<()> {
|
||||||
self.coords.entomb(writer)
|
self.coords.entomb(writer)
|
||||||
|
@ -53,7 +54,8 @@ where Vector4<N>: Abomonation
|
||||||
impl<N: SimdRealField + Eq> Eq for Quaternion<N> where N::Element: SimdRealField {}
|
impl<N: SimdRealField + Eq> Eq for Quaternion<N> where N::Element: SimdRealField {}
|
||||||
|
|
||||||
impl<N: SimdRealField> PartialEq for Quaternion<N>
|
impl<N: SimdRealField> PartialEq for Quaternion<N>
|
||||||
where N::Element: SimdRealField
|
where
|
||||||
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
fn eq(&self, rhs: &Self) -> bool {
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
self.coords == rhs.coords ||
|
self.coords == rhs.coords ||
|
||||||
|
@ -79,20 +81,26 @@ impl<N: Scalar + SimdValue> Clone for Quaternion<N> {
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<N: SimdRealField> Serialize for Quaternion<N>
|
impl<N: SimdRealField> Serialize for Quaternion<N>
|
||||||
where Owned<N, U4>: Serialize
|
where
|
||||||
|
Owned<N, U4>: Serialize,
|
||||||
{
|
{
|
||||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
where S: Serializer {
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
self.coords.serialize(serializer)
|
self.coords.serialize(serializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "serde-serialize")]
|
#[cfg(feature = "serde-serialize")]
|
||||||
impl<'a, N: SimdRealField> Deserialize<'a> for Quaternion<N>
|
impl<'a, N: SimdRealField> Deserialize<'a> for Quaternion<N>
|
||||||
where Owned<N, U4>: Deserialize<'a>
|
where
|
||||||
|
Owned<N, U4>: Deserialize<'a>,
|
||||||
{
|
{
|
||||||
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
fn deserialize<Des>(deserializer: Des) -> Result<Self, Des::Error>
|
||||||
where Des: Deserializer<'a> {
|
where
|
||||||
|
Des: Deserializer<'a>,
|
||||||
|
{
|
||||||
let coords = Vector4::<N>::deserialize(deserializer)?;
|
let coords = Vector4::<N>::deserialize(deserializer)?;
|
||||||
|
|
||||||
Ok(Self::from(coords))
|
Ok(Self::from(coords))
|
||||||
|
@ -100,7 +108,8 @@ where Owned<N, U4>: Deserialize<'a>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> Quaternion<N>
|
impl<N: SimdRealField> Quaternion<N>
|
||||||
where N::Element: SimdRealField
|
where
|
||||||
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
/// Moves this unit quaternion into one that owns its data.
|
/// Moves this unit quaternion into one that owns its data.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -289,10 +298,13 @@ where N::Element: SimdRealField
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> Quaternion<N>
|
impl<N: SimdRealField> Quaternion<N>
|
||||||
where N::Element: SimdRealField
|
where
|
||||||
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
/// Inverts this quaternion if it is not zero.
|
/// Inverts this quaternion if it is not zero.
|
||||||
///
|
///
|
||||||
|
/// This method also does not works with SIMD components (see `simd_try_inverse` instead).
|
||||||
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[macro_use] extern crate approx;
|
/// # #[macro_use] extern crate approx;
|
||||||
|
@ -312,7 +324,9 @@ where N::Element: SimdRealField
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
||||||
pub fn try_inverse(&self) -> Option<Self>
|
pub fn try_inverse(&self) -> Option<Self>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
let mut res = self.clone();
|
let mut res = self.clone();
|
||||||
|
|
||||||
if res.try_inverse_mut() {
|
if res.try_inverse_mut() {
|
||||||
|
@ -322,6 +336,9 @@ where N::Element: SimdRealField
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Attempt to inverse this quaternion.
|
||||||
|
///
|
||||||
|
/// This method also works with SIMD components.
|
||||||
#[inline]
|
#[inline]
|
||||||
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
#[must_use = "Did you mean to use try_inverse_mut()?"]
|
||||||
pub fn simd_try_inverse(&self) -> SimdOption<Self> {
|
pub fn simd_try_inverse(&self) -> SimdOption<Self> {
|
||||||
|
@ -383,7 +400,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn project(&self, other: &Self) -> Option<Self>
|
pub fn project(&self, other: &Self) -> Option<Self>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.inner(other).right_div(other)
|
self.inner(other).right_div(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -403,7 +422,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reject(&self, other: &Self) -> Option<Self>
|
pub fn reject(&self, other: &Self) -> Option<Self>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.outer(other).right_div(other)
|
self.outer(other).right_div(other)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +444,9 @@ where N::Element: SimdRealField
|
||||||
/// assert_eq!(axis, Some(Vector3::x_axis()));
|
/// assert_eq!(axis, Some(Vector3::x_axis()));
|
||||||
/// ```
|
/// ```
|
||||||
pub fn polar_decomposition(&self) -> (N, N, Option<Unit<Vector3<N>>>)
|
pub fn polar_decomposition(&self) -> (N, N, Option<Unit<Vector3<N>>>)
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
if let Some((q, n)) = Unit::try_new_and_get(*self, N::zero()) {
|
if let Some((q, n)) = Unit::try_new_and_get(*self, N::zero()) {
|
||||||
if let Some(axis) = Unit::try_new(self.vector().clone_owned(), N::zero()) {
|
if let Some(axis) = Unit::try_new(self.vector().clone_owned(), N::zero()) {
|
||||||
let angle = q.angle() / crate::convert(2.0f64);
|
let angle = q.angle() / crate::convert(2.0f64);
|
||||||
|
@ -640,7 +663,9 @@ where N::Element: SimdRealField
|
||||||
/// Calculates B<sup>-1</sup> * A where A = self, B = other.
|
/// Calculates B<sup>-1</sup> * A where A = self, B = other.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn left_div(&self, other: &Self) -> Option<Self>
|
pub fn left_div(&self, other: &Self) -> Option<Self>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
other.try_inverse().map(|inv| inv * self)
|
other.try_inverse().map(|inv| inv * self)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,7 +685,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn right_div(&self, other: &Self) -> Option<Self>
|
pub fn right_div(&self, other: &Self) -> Option<Self>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
other.try_inverse().map(|inv| self * inv)
|
other.try_inverse().map(|inv| self * inv)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -753,7 +780,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tan(&self) -> Self
|
pub fn tan(&self) -> Self
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.sin().right_div(&self.cos()).unwrap()
|
self.sin().right_div(&self.cos()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -769,7 +798,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn atan(&self) -> Self
|
pub fn atan(&self) -> Self
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
let u = Self::from_imag(self.imag().normalize());
|
let u = Self::from_imag(self.imag().normalize());
|
||||||
let num = u + self;
|
let num = u + self;
|
||||||
let den = u - self;
|
let den = u - self;
|
||||||
|
@ -857,7 +888,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn tanh(&self) -> Self
|
pub fn tanh(&self) -> Self
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.sinh().right_div(&self.cosh()).unwrap()
|
self.sinh().right_div(&self.cosh()).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -907,8 +940,7 @@ impl<N: RealField + RelativeEq<Epsilon = N>> RelativeEq for Quaternion<N> {
|
||||||
other: &Self,
|
other: &Self,
|
||||||
epsilon: Self::Epsilon,
|
epsilon: Self::Epsilon,
|
||||||
max_relative: Self::Epsilon,
|
max_relative: Self::Epsilon,
|
||||||
) -> bool
|
) -> bool {
|
||||||
{
|
|
||||||
self.as_vector().relative_eq(other.as_vector(), epsilon, max_relative) ||
|
self.as_vector().relative_eq(other.as_vector(), epsilon, max_relative) ||
|
||||||
// Account for the double-covering of S², i.e. q = -q
|
// Account for the double-covering of S², i.e. q = -q
|
||||||
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.relative_eq(&-*b, epsilon, max_relative))
|
self.as_vector().iter().zip(other.as_vector().iter()).all(|(a, b)| a.relative_eq(&-*b, epsilon, max_relative))
|
||||||
|
@ -967,7 +999,8 @@ impl<N: SimdRealField> Normed for Quaternion<N> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N: SimdRealField> UnitQuaternion<N>
|
impl<N: SimdRealField> UnitQuaternion<N>
|
||||||
where N::Element: SimdRealField
|
where
|
||||||
|
N::Element: SimdRealField,
|
||||||
{
|
{
|
||||||
/// The rotation angle in [0; pi] of this unit quaternion.
|
/// The rotation angle in [0; pi] of this unit quaternion.
|
||||||
///
|
///
|
||||||
|
@ -1120,7 +1153,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn slerp(&self, other: &Self, t: N) -> Self
|
pub fn slerp(&self, other: &Self, t: N) -> Self
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.try_slerp(other, t, N::default_epsilon())
|
self.try_slerp(other, t, N::default_epsilon())
|
||||||
.expect("Quaternion slerp: ambiguous configuration.")
|
.expect("Quaternion slerp: ambiguous configuration.")
|
||||||
}
|
}
|
||||||
|
@ -1137,7 +1172,9 @@ where N::Element: SimdRealField
|
||||||
/// must be to return `None`.
|
/// must be to return `None`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn try_slerp(&self, other: &Self, t: N, epsilon: N) -> Option<Self>
|
pub fn try_slerp(&self, other: &Self, t: N, epsilon: N) -> Option<Self>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
let coords = if self.coords.dot(&other.coords) < N::zero() {
|
let coords = if self.coords.dot(&other.coords) < N::zero() {
|
||||||
Unit::new_unchecked(self.coords).try_slerp(
|
Unit::new_unchecked(self.coords).try_slerp(
|
||||||
&Unit::new_unchecked(-other.coords),
|
&Unit::new_unchecked(-other.coords),
|
||||||
|
@ -1194,7 +1231,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn axis(&self) -> Option<Unit<Vector3<N>>>
|
pub fn axis(&self) -> Option<Unit<Vector3<N>>>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
let v = if self.quaternion().scalar() >= N::zero() {
|
let v = if self.quaternion().scalar() >= N::zero() {
|
||||||
self.as_ref().vector().clone_owned()
|
self.as_ref().vector().clone_owned()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1216,7 +1255,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn scaled_axis(&self) -> Vector3<N>
|
pub fn scaled_axis(&self) -> Vector3<N>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
if let Some(axis) = self.axis() {
|
if let Some(axis) = self.axis() {
|
||||||
axis.into_inner() * self.angle()
|
axis.into_inner() * self.angle()
|
||||||
} else {
|
} else {
|
||||||
|
@ -1242,7 +1283,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn axis_angle(&self) -> Option<(Unit<Vector3<N>>, N)>
|
pub fn axis_angle(&self) -> Option<(Unit<Vector3<N>>, N)>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.axis().map(|axis| (axis, self.angle()))
|
self.axis().map(|axis| (axis, self.angle()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1270,7 +1313,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn ln(&self) -> Quaternion<N>
|
pub fn ln(&self) -> Quaternion<N>
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
if let Some(v) = self.axis() {
|
if let Some(v) = self.axis() {
|
||||||
Quaternion::from_imag(v.into_inner() * self.angle())
|
Quaternion::from_imag(v.into_inner() * self.angle())
|
||||||
} else {
|
} else {
|
||||||
|
@ -1296,7 +1341,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn powf(&self, n: N) -> Self
|
pub fn powf(&self, n: N) -> Self
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
if let Some(v) = self.axis() {
|
if let Some(v) = self.axis() {
|
||||||
Self::from_axis_angle(&v, self.angle() * n)
|
Self::from_axis_angle(&v, self.angle() * n)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1357,7 +1404,9 @@ where N::Element: SimdRealField
|
||||||
#[inline]
|
#[inline]
|
||||||
#[deprecated(note = "This is renamed to use `.euler_angles()`.")]
|
#[deprecated(note = "This is renamed to use `.euler_angles()`.")]
|
||||||
pub fn to_euler_angles(&self) -> (N, N, N)
|
pub fn to_euler_angles(&self) -> (N, N, N)
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.euler_angles()
|
self.euler_angles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1377,7 +1426,9 @@ where N::Element: SimdRealField
|
||||||
/// ```
|
/// ```
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn euler_angles(&self) -> (N, N, N)
|
pub fn euler_angles(&self) -> (N, N, N)
|
||||||
where N: RealField {
|
where
|
||||||
|
N: RealField,
|
||||||
|
{
|
||||||
self.to_rotation_matrix().euler_angles()
|
self.to_rotation_matrix().euler_angles()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1533,8 +1584,7 @@ impl<N: RealField + RelativeEq<Epsilon = N>> RelativeEq for UnitQuaternion<N> {
|
||||||
other: &Self,
|
other: &Self,
|
||||||
epsilon: Self::Epsilon,
|
epsilon: Self::Epsilon,
|
||||||
max_relative: Self::Epsilon,
|
max_relative: Self::Epsilon,
|
||||||
) -> bool
|
) -> bool {
|
||||||
{
|
|
||||||
self.as_ref()
|
self.as_ref()
|
||||||
.relative_eq(other.as_ref(), epsilon, max_relative)
|
.relative_eq(other.as_ref(), epsilon, max_relative)
|
||||||
}
|
}
|
||||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -79,7 +79,7 @@ an optimized set of tools for computer graphics and physics. Those features incl
|
||||||
#![deny(non_upper_case_globals)]
|
#![deny(non_upper_case_globals)]
|
||||||
#![deny(unused_qualifications)]
|
#![deny(unused_qualifications)]
|
||||||
#![deny(unused_results)]
|
#![deny(unused_results)]
|
||||||
#![allow(missing_docs)] // XXX: deny that
|
#![deny(missing_docs)]
|
||||||
#![doc(
|
#![doc(
|
||||||
html_favicon_url = "https://nalgebra.org/img/favicon.ico",
|
html_favicon_url = "https://nalgebra.org/img/favicon.ico",
|
||||||
html_root_url = "https://nalgebra.org/rustdoc"
|
html_root_url = "https://nalgebra.org/rustdoc"
|
||||||
|
@ -190,7 +190,9 @@ pub fn zero<T: Zero>() -> T {
|
||||||
/// The range must not be empty.
|
/// The range must not be empty.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn wrap<T>(mut val: T, min: T, max: T) -> T
|
pub fn wrap<T>(mut val: T, min: T, max: T) -> T
|
||||||
where T: Copy + PartialOrd + ClosedAdd + ClosedSub {
|
where
|
||||||
|
T: Copy + PartialOrd + ClosedAdd + ClosedSub,
|
||||||
|
{
|
||||||
assert!(min < max, "Invalid wrapping bounds.");
|
assert!(min < max, "Invalid wrapping bounds.");
|
||||||
let width = max - min;
|
let width = max - min;
|
||||||
|
|
||||||
|
@ -390,7 +392,9 @@ pub fn partial_sort2<'a, T: PartialOrd>(a: &'a T, b: &'a T) -> Option<(&'a T, &'
|
||||||
/// * [distance_squared](fn.distance_squared.html)
|
/// * [distance_squared](fn.distance_squared.html)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn center<N: SimdComplexField, D: DimName>(p1: &Point<N, D>, p2: &Point<N, D>) -> Point<N, D>
|
pub fn center<N: SimdComplexField, D: DimName>(p1: &Point<N, D>, p2: &Point<N, D>) -> Point<N, D>
|
||||||
where DefaultAllocator: Allocator<N, D> {
|
where
|
||||||
|
DefaultAllocator: Allocator<N, D>,
|
||||||
|
{
|
||||||
((&p1.coords + &p2.coords) * convert::<_, N>(0.5)).into()
|
((&p1.coords + &p2.coords) * convert::<_, N>(0.5)).into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue