From 289fc7febc38f2d31390c8c6cadb437c937bd0dc Mon Sep 17 00:00:00 2001 From: Oliver Sander <sander@igpm.rwth-aachen.de> Date: Fri, 12 Oct 2007 08:43:25 +0000 Subject: [PATCH] add assignment from scalar, the inverse exponential, its derivative, and conjugation [[Imported from SVN: r1678]] --- src/quaternion.hh | 72 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/src/quaternion.hh b/src/quaternion.hh index b94ac4bd..d71a4560 100644 --- a/src/quaternion.hh +++ b/src/quaternion.hh @@ -43,6 +43,13 @@ public: (*this)[3] = std::cos(angle/2); } + /** \brief Assignment from a scalar */ + Quaternion<T>& operator=(const T& v) { + for (int i=0; i<4; i++) + (*this)[i] = v; + return (*this); + } + /** \brief Return the identity element */ static Quaternion<T> identity() { Quaternion<T> id; @@ -102,6 +109,60 @@ public: return result; } + /** \brief The inverse of the exponential map */ + static Dune::FieldVector<T,3> expInv(const Quaternion<T>& q) { + // Compute v = exp^{-1} q + // Due to numerical dirt, q[3] may be larger than 1. + // In that case, use 1 instead of q[3]. + Dune::FieldVector<T,3> v; + if (q[3] > 1.0) { + + v = 0; + + } else { + + T invSinc = 1/sincHalf(2*std::acos(q[3])); + + v[0] = q[0] * invSinc; + v[1] = q[1] * invSinc; + v[2] = q[2] * invSinc; + + } + return v; + } + + /** \brief The derivative of the inverse of the exponential map, evaluated at q */ + static Dune::FieldMatrix<T,3,4> DexpInv(const Quaternion<T>& q) { + + // Compute v = exp^{-1} q + Dune::FieldVector<T,3> v = expInv(q); + + // The derivative of exp at v + Dune::FieldMatrix<T,4,3> A = Dexp(v); + + // Compute the Moore-Penrose pseudo inverse A^+ = (A^T A)^{-1} A^T + Dune::FieldMatrix<T,3,3> ATA; + + for (int i=0; i<3; i++) + for (int j=0; j<3; j++) { + ATA[i][j] = 0; + for (int k=0; k<4; k++) + ATA[i][j] += A[k][i] * A[k][j]; + } + + ATA.invert(); + + Dune::FieldMatrix<T,3,4> APseudoInv; + for (int i=0; i<3; i++) + for (int j=0; j<4; j++) { + APseudoInv[i][j] = 0; + for (int k=0; k<3; k++) + APseudoInv[i][j] += ATA[i][k] * A[j][k]; + } + + return APseudoInv; + } + /** \brief Right quaternion multiplication */ Quaternion<T> mult(const Quaternion<T>& other) const { Quaternion<T> q; @@ -235,14 +296,21 @@ public: return result; } - /** \brief Invert the quaternion */ - void invert() { + /** \brief Conjugate the quaternion */ + void conjugate() { (*this)[0] *= -1; (*this)[1] *= -1; (*this)[2] *= -1; + } + + /** \brief Invert the quaternion */ + void invert() { + + conjugate(); (*this) /= this->two_norm2(); + } static Dune::FieldVector<T,3> difference(const Quaternion<T>& a, const Quaternion<T>& b) { -- GitLab