//! All matrix multiplication in this module is in row-vector notation, //! i.e. a vector `v` is transformed with `v * T`, and if you want to apply `T1` //! before `T2` you use `T1 * T2`
#[cfg(feature = "bytemuck")] use bytemuck::{Pod, Zeroable}; use num_traits::real::Real; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize};
/// A rigid transformation. All lengths are preserved under such a transformation. /// /// /// Internally, this is a rotation and a translation, with the rotation /// applied first (i.e. `Rotation * Translation`, in row-vector notation) /// /// This can be more efficient to use over full matrices, especially if you /// have to deal with the decomposed quantities often. #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[repr(C)] pubstruct RigidTransform3D<T, Src, Dst> { pub rotation: Rotation3D<T, Src, Dst>, pub translation: Vector3D<T, Dst>,
}
impl<T, Src, Dst> RigidTransform3D<T, Src, Dst> { /// Construct a new rigid transformation, where the `rotation` applies first #[inline] pubconstfn new(rotation: Rotation3D<T, Src, Dst>, translation: Vector3D<T, Dst>) -> Self { Self {
rotation,
translation,
}
}
}
/// Construct a new rigid transformation, where the `translation` applies first #[inline] pubfn new_from_reversed(
translation: Vector3D<T, Src>,
rotation: Rotation3D<T, Src, Dst>,
) -> Self { // T * R // = (R * R^-1) * T * R // = R * (R^-1 * T * R) // = R * T' // // T' = (R^-1 * T * R) is also a translation matrix // It is equivalent to the translation matrix obtained by rotating the // translation by R
let translation = rotation.transform_vector3d(translation); Self {
rotation,
translation,
}
}
/// Decompose this into a translation and an rotation to be applied in the opposite order /// /// i.e., the translation is applied _first_ #[inline] pubfn decompose_reversed(&self) -> (Vector3D<T, Src>, Rotation3D<T, Src, Dst>) { // self = R * T // = R * T * (R^-1 * R) // = (R * T * R^-1) * R) // = T' * R // // T' = (R^ * T * R^-1) is T rotated by R^-1
let translation = self.rotation.inverse().transform_vector3d(self.translation);
(translation, self.rotation)
}
/// Returns the multiplication of the two transforms such that /// other's transformation applies after self's transformation. /// /// i.e., this produces `self * other` in row-vector notation #[inline] pubfn then<Dst2>(
&self,
other: &RigidTransform3D<T, Dst, Dst2>,
) -> RigidTransform3D<T, Src, Dst2> { // self = R1 * T1 // other = R2 * T2 // result = R1 * T1 * R2 * T2 // = R1 * (R2 * R2^-1) * T1 * R2 * T2 // = (R1 * R2) * (R2^-1 * T1 * R2) * T2 // = R' * T' * T2 // = R' * T'' // // (R2^-1 * T2 * R2^) = T' = T2 rotated by R2 // R1 * R2 = R' // T' * T2 = T'' = vector addition of translations T2 and T'
let t_prime = other.rotation.transform_vector3d(self.translation); let r_prime = self.rotation.then(&other.rotation); let t_prime2 = t_prime + other.translation;
RigidTransform3D {
rotation: r_prime,
translation: t_prime2,
}
}
/// Inverts the transformation #[inline] pubfn inverse(&self) -> RigidTransform3D<T, Dst, Src> { // result = (self)^-1 // = (R * T)^-1 // = T^-1 * R^-1 // = (R^-1 * R) * T^-1 * R^-1 // = R^-1 * (R * T^-1 * R^-1) // = R' * T' // // T' = (R * T^-1 * R^-1) = (-T) rotated by R^-1 // R' = R^-1 // // An easier way of writing this is to use new_from_reversed() with R^-1 and T^-1
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.