From 624486f26ecf430796a7d1c51c0846d4b428052e Mon Sep 17 00:00:00 2001
From: Oliver Sander <sander@igpm.rwth-aachen.de>
Date: Tue, 28 Feb 2006 09:51:38 +0000
Subject: [PATCH] A quaternion class

[[Imported from SVN: r736]]
---
 src/quaternion.hh | 72 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 src/quaternion.hh

diff --git a/src/quaternion.hh b/src/quaternion.hh
new file mode 100644
index 00000000..00a0f214
--- /dev/null
+++ b/src/quaternion.hh
@@ -0,0 +1,72 @@
+#ifndef QUATERNION_HH
+#define QUATERNION_HH
+
+#include <dune/common/fvector.hh>
+#include <dune/common/exceptions.hh>
+
+template <class T>
+class Quaternion : public Dune::FieldVector<T,4>
+{
+public:
+
+    /** \brief The exponential map from \f$ \mathfrak{so}(3) \f$ to \f$ SO(3) \f$
+     */
+    static Quaternion<T> exp(const T& v0, const T& v1, const T& v2) {
+        Quaternion<T> q;
+
+        T normV = std::sqrt(v0*v0 + v1*v1 + v2*v2);
+        T sin   = std::sin(normV/2)/normV;
+
+        q[0] = sin * v0;
+        q[1] = sin * v1;
+        q[2] = sin * v2;
+        q[3] = std::cos(normV/2);
+
+        return q;
+    }
+
+    /** \brief Right quaternion multiplication */
+    Quaternion<T> mult(const Quaternion<T>& other) {
+        Quaternion<T> q;
+        q[0] =   (*this)[3]*other[0] - (*this)[2]*other[1] + (*this)[1]*other[2] + (*this)[0]*other[3];
+        q[1] =   (*this)[2]*other[0] + (*this)[3]*other[1] - (*this)[0]*other[2] + (*this)[1]*other[3];
+        q[2] = - (*this)[1]*other[0] + (*this)[0]*other[1] + (*this)[3]*other[2] + (*this)[2]*other[3];
+        q[3] = - (*this)[0]*other[0] - (*this)[1]*other[1] - (*this)[2]*other[2] + (*this)[3]*other[3];
+
+        return q;
+    }
+    /** \brief Return the tripel of director vectors represented by a unit quaternion
+
+    The formulas are taken from Dichmann, Li, Maddocks, (2.6.4), (2.6.5), (2.6.6)
+    */
+    Dune::FieldVector<T,3> director(int i) const {
+        
+        Dune::FieldVector<T,3> d;
+        const Dune::FieldVector<T,4>& q = *this;   // simpler notation
+
+        if (i==0) {
+            d[0] = q[0]*q[0] - q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
+            d[1] = 2 * (q[0]*q[1] + q[2]*q[3]);
+            d[2] = 2 * (q[0]*q[2] - q[1]*q[3]);
+        } else if (i==1) {
+            d[0] = 2 * (q[0]*q[1] - q[2]*q[3]);
+            d[1] = -q[0]*q[0] + q[1]*q[1] - q[2]*q[2] + q[3]*q[3];
+            d[2] = 2 * (q[1]*q[2] + q[0]*q[3]);
+        } else if (i==2) {
+            d[0] = 2 * (q[0]*q[2] + q[1]*q[3]);
+            d[1] = 2 * (q[1]*q[2] - q[0]*q[3]);
+            d[2] = -q[0]*q[0] - q[1]*q[1] + q[2]*q[2] + q[3]*q[3];
+        } else
+            DUNE_THROW(Dune::Exception, "Nonexisting director " << i << " requested!");
+
+        return d;
+    }
+            
+    /** \brief Turn quaternion into a unit quaternion by dividing by its Euclidean norm */
+    void normalize() {
+        (*this) /= this->two_norm();
+    }
+
+};
+
+#endif
-- 
GitLab