From 6139372c384b14f2f43e01c6c9a3f02a7dc422b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Crozet=20S=C3=A9bastien?= Date: Mon, 22 Feb 2021 14:26:25 +0100 Subject: [PATCH] Add from_basis_unchecked to rotation types. --- src/geometry/quaternion_construction.rs | 11 +++++++++++ src/geometry/rotation_specialization.rs | 24 ++++++++++++++++++++++- src/geometry/unit_complex_construction.rs | 14 ++++++++++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/geometry/quaternion_construction.rs b/src/geometry/quaternion_construction.rs index 03d87d39..a26deb1a 100644 --- a/src/geometry/quaternion_construction.rs +++ b/src/geometry/quaternion_construction.rs @@ -266,6 +266,17 @@ where Self::new_unchecked(q) } + /// Builds an unit quaternion from a basis assumed to be orthonormal. + /// + /// In order to get a valid unit-quaternion, the input must be an + /// orthonormal basis, i.e., all vectors are normalized, and the are + /// all orthogonal to each other. These invariants are not checked + /// by this method. + pub fn from_basis_unchecked(basis: &[Vector3; 3]) -> Self { + let rot = Rotation3::from_basis_unchecked(basis); + Self::from_rotation_matrix(&rot) + } + /// Builds an unit quaternion from a rotation matrix. /// /// # Example diff --git a/src/geometry/rotation_specialization.rs b/src/geometry/rotation_specialization.rs index afc180d8..fcaa8667 100644 --- a/src/geometry/rotation_specialization.rs +++ b/src/geometry/rotation_specialization.rs @@ -12,7 +12,7 @@ use std::ops::Neg; use crate::base::dimension::{U1, U2, U3}; use crate::base::storage::Storage; -use crate::base::{Matrix2, Matrix3, MatrixN, Unit, Vector, Vector1, Vector3, VectorN}; +use crate::base::{Matrix2, Matrix3, MatrixN, Unit, Vector, Vector1, Vector2, Vector3, VectorN}; use crate::geometry::{Rotation2, Rotation3, UnitComplex, UnitQuaternion}; @@ -53,6 +53,17 @@ impl Rotation2 { /// # Construction from an existing 2D matrix or rotations impl Rotation2 { + /// Builds a rotation from a basis assumed to be orthonormal. + /// + /// In order to get a valid unit-quaternion, the input must be an + /// orthonormal basis, i.e., all vectors are normalized, and the are + /// all orthogonal to each other. These invariants are not checked + /// by this method. + pub fn from_basis_unchecked(basis: &[Vector2; 2]) -> Self { + let mat = Matrix2::from_columns(&basis[..]); + Self::from_matrix_unchecked(mat) + } + /// Builds a rotation matrix by extracting the rotation part of the given transformation `m`. /// /// This is an iterative method. See `.from_matrix_eps` to provide mover @@ -655,6 +666,17 @@ where } } + /// Builds a rotation from a basis assumed to be orthonormal. + /// + /// In order to get a valid unit-quaternion, the input must be an + /// orthonormal basis, i.e., all vectors are normalized, and the are + /// all orthogonal to each other. These invariants are not checked + /// by this method. + pub fn from_basis_unchecked(basis: &[Vector3; 3]) -> Self { + let mat = Matrix3::from_columns(&basis[..]); + Self::from_matrix_unchecked(mat) + } + /// Builds a rotation matrix by extracting the rotation part of the given transformation `m`. /// /// This is an iterative method. See `.from_matrix_eps` to provide mover diff --git a/src/geometry/unit_complex_construction.rs b/src/geometry/unit_complex_construction.rs index 65d36888..acdbac8a 100644 --- a/src/geometry/unit_complex_construction.rs +++ b/src/geometry/unit_complex_construction.rs @@ -8,7 +8,7 @@ use rand::Rng; use crate::base::dimension::{U1, U2}; use crate::base::storage::Storage; -use crate::base::{Matrix2, Unit, Vector}; +use crate::base::{Matrix2, Unit, Vector, Vector2}; use crate::geometry::{Rotation2, UnitComplex}; use simba::scalar::RealField; use simba::simd::SimdRealField; @@ -164,6 +164,18 @@ where Self::new_unchecked(Complex::new(rotmat[(0, 0)], rotmat[(1, 0)])) } + /// Builds a rotation from a basis assumed to be orthonormal. + /// + /// In order to get a valid unit-quaternion, the input must be an + /// orthonormal basis, i.e., all vectors are normalized, and the are + /// all orthogonal to each other. These invariants are not checked + /// by this method. + pub fn from_basis_unchecked(basis: &[Vector2; 2]) -> Self { + let mat = Matrix2::from_columns(&basis[..]); + let rot = Rotation2::from_matrix_unchecked(mat); + Self::from_rotation_matrix(&rot) + } + /// Builds an unit complex by extracting the rotation part of the given transformation `m`. /// /// This is an iterative method. See `.from_matrix_eps` to provide mover