CellModules
quaternion.h
Go to the documentation of this file.
1#ifndef MECACELL_QUATERNION_H
2#define MECACELL_QUATERNION_H
3#include <cmath>
4#include "../utilities/utils.hpp"
5
6#define dispVec(v) "(" << v.x() << "," << v.y() << "," << v.z() << ")"
7
8namespace MecaCell {
9template <typename V> struct Quaternion {
10 V v;
11 double w;
12 Quaternion(const double& angle, const V& n) {
13 double halfangle = angle * 0.5;
14 w = cos(halfangle);
15 v = n * sin(halfangle);
16 }
17 Quaternion(const V& v0, const V& v1) {
18 V v2 = v0.normalized();
19 V v3 = v1.normalized();
20 double sc = min<double>(1.0, max<double>(-1.0, v2.dot(v3)));
21 if (sc < -0.9999) {
22 *this = Quaternion(M_PI, v2.ortho());
23 } else {
24 v = v2.cross(v3);
25 w = 1.0 + sc;
26 normalize();
27 }
28 }
29 Quaternion(const Quaternion& q) : v(q.v), w(q.w) {}
30 Quaternion(const double& x, const double& y, const double& z, const double& ww)
31 : v(x, y, z), w(ww) {}
32 Quaternion() : v(0, 1, 0), w(0) {}
33 Quaternion operator*(const Quaternion& q2) const {
34 return Quaternion(v.x() * q2.w + v.y() * q2.v.z() - v.z() * q2.v.y() + w * q2.v.x(),
35 -v.x() * q2.v.z() + v.y() * q2.w + v.z() * q2.v.x() + w * q2.v.y(),
36 v.x() * q2.v.y() - v.y() * q2.v.x() + v.z() * q2.w + w * q2.v.z(),
37 -v.x() * q2.v.x() - v.y() * q2.v.y() - v.z() * q2.v.z() + w * q2.w);
38 }
39 V operator*(const V& vec) const {
40 V vcV = 2.0 * v.cross(vec);
41 return vec + w * vcV + v.cross(vcV);
42 }
43
44 V getAxis() const {
45 assert(w <= 1.0);
46 double s = sqrt(1.0 - w * w);
47 if (s == 0) return V(1, 0, 0);
48 return v / s;
49 }
50 double getAngle() const {
51 assert(w <= 1.0);
52 return 2.0 * acos(w);
53 }
54
56 double magnitude = sqrt(w * w + v.x() * v.x() + v.y() * v.y() + v.z() * v.z());
57 return Quaternion(v.x() / magnitude, v.y() / magnitude, v.z() / magnitude,
58 w / magnitude);
59 }
60 void normalize() {
61 double magnitude = sqrt(w * w + v.x() * v.x() + v.y() * v.y() + v.z() * v.z());
62 w = min<double>(w / magnitude, 1.0);
63 v = v / magnitude;
64 }
65
67 normalize();
68 double s = sqrt(1.0 - w * w);
69 if (s == 0) return Rotation<V>(V(1, 0, 0), acos(w) * 2.0);
70 return Rotation<V>(v / s, acos(w) * 2.0);
71 }
72};
73} // namespace MecaCell
74#endif
this file contains various miscellanious utility functions & helpers *
double acos(double x)
Computes the arc cosine of a number.
Definition: std.hpp:113
double sin(double x)
Computes the sine of a number.
Definition: std.hpp:53
double sqrt(double x)
Computes the square root of a number.
Definition: std.hpp:32
double cos(double x)
Computes the cosine of a number.
Definition: std.hpp:63
Quaternion normalized() const
Definition: quaternion.h:55
double getAngle() const
Definition: quaternion.h:50
Quaternion(const double &x, const double &y, const double &z, const double &ww)
Definition: quaternion.h:30
Quaternion(const double &angle, const V &n)
Definition: quaternion.h:12
Quaternion operator*(const Quaternion &q2) const
Definition: quaternion.h:33
Quaternion(const V &v0, const V &v1)
Definition: quaternion.h:17
Rotation< V > toAxisAngle()
Definition: quaternion.h:66
V operator*(const V &vec) const
Definition: quaternion.h:39
Quaternion(const Quaternion &q)
Definition: quaternion.h:29