OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
Quaternion.cpp
Go to the documentation of this file.
3#include "Physics/Physics.h"
6
7namespace {
8 Vector_t normalize(const Vector_t & vec)
9 {
10 double length = std::sqrt(dot(vec, vec));
11
12#ifndef NOPAssert
13 if (length < 1e-12)
14 throw GeneralClassicException("normalize()",
15 "length of vector less than 1e-12");
16#endif
17
18 return vec / length;
19 }
20}
21
23 Vektor<double, 4>(0.0)
24{
25 (*this)(0) = std::sqrt(std::max(0.0, 1 + M(0, 0) + M(1, 1) + M(2, 2))) / 2;
26 (*this)(1) = std::sqrt(std::max(0.0, 1 + M(0, 0) - M(1, 1) - M(2, 2))) / 2;
27 (*this)(2) = std::sqrt(std::max(0.0, 1 - M(0, 0) + M(1, 1) - M(2, 2))) / 2;
28 (*this)(3) = std::sqrt(std::max(0.0, 1 - M(0, 0) - M(1, 1) + M(2, 2))) / 2;
29 (*this)(1) = std::abs(M(2, 1) - M(1, 2)) > 0? std::copysign((*this)(1), M(2, 1) - M(1, 2)): 0.0;
30 (*this)(2) = std::abs(M(0, 2) - M(2, 0)) > 0? std::copysign((*this)(2), M(0, 2) - M(2, 0)): 0.0;
31 (*this)(3) = std::abs(M(1, 0) - M(0, 1)) > 0? std::copysign((*this)(3), M(1, 0) - M(0, 1)): 0.0;
32}
33
35{
36 const double tol = 1e-12;
37
38 u = normalize(u);
39 ref = normalize(ref);
40
41 Vector_t axis = cross(u, ref);
42 double normAxis = std::sqrt(dot(axis,axis));
43
44 if (normAxis < tol) {
45 if (std::abs(dot(u, ref) - 1.0) < tol) {
46 return Quaternion(1.0, Vector_t(0.0));
47 }
48 // vectors are parallel or antiparallel
49 do { // find any vector in plane with ref as normal
50 double u = IpplRandom();
51 double v = 2 * Physics::pi * IpplRandom();
52 axis(0) = std::sqrt(1 - u*u) * std::cos(v);
53 axis(1) = std::sqrt(1 - u*u) * std::sin(v);
54 axis(2) = u;
55 } while(std::abs(dot(axis, ref)) > 0.9);
56
57 axis -= dot(axis, ref) * ref;
58 axis = normalize(axis);
59
60 return Quaternion(0, axis);
61 }
62
63 axis /= normAxis;
64
65 double cosAngle = sqrt(0.5 * (1 + dot(u, ref)));
66 double sinAngle = sqrt(1 - cosAngle * cosAngle);
67
68 return Quaternion(cosAngle, sinAngle * axis);
69}
70
71Quaternion Quaternion::operator*(const double & d) const
72{
73 Quaternion result(d * this->real(), d * this->imag());
74
75 return result;
76}
77
79{
80 Quaternion result(*this);
81 return result *= other;
82}
83
85{
86 Vector_t imagThis = this->imag();
87 Vector_t imagOther = other.imag();
88
89 *this = Quaternion((*this)(0) * other(0) - dot(imagThis, imagOther),
90 (*this)(0) * imagOther + other(0) * imagThis + cross(imagThis, imagOther));
91
92 return *this;
93}
94
95Quaternion Quaternion::operator/(const double & d) const
96{
97 Quaternion result(this->real() / d, this->imag() / d);
98
99 return result;
100}
101
103{
104#ifndef NOPAssert
105 if (this->Norm() < 1e-12)
106 throw GeneralClassicException("Quaternion::normalize()",
107 "length of quaternion less than 1e-12");
108#endif
109
110 (*this) /= this->length();
111
112 return (*this);
113}
114
116{
117 Quaternion returnValue = conjugate();
118
119 return returnValue.normalize();
120}
121
123{
124#ifndef NOPAssert
125 if (!this->isUnit())
126 throw GeneralClassicException("Quaternion::rotate()",
127 "quaternion isn't unit quaternion. Norm: " + std::to_string(this->Norm()));
128#endif
129
130 Quaternion quat(vec);
131
132 return ((*this) * (quat * (*this).conjugate())).imag();
133}
134
136{
137 Quaternion rot(*this);
138 rot.normalize();
139
140 matrix_t mat(3, 3);
141 mat(0, 0) = 1 - 2 * (rot(2) * rot(2) + rot(3) * rot(3));
142 mat(0, 1) = 2 * (-rot(0) * rot(3) + rot(1) * rot(2));
143 mat(0, 2) = 2 * (rot(0) * rot(2) + rot(1) * rot(3));
144 mat(1, 0) = 2 * (rot(0) * rot(3) + rot(1) * rot(2));
145 mat(1, 1) = 1 - 2 * (rot(1) * rot(1) + rot(3) * rot(3));
146 mat(1, 2) = 2 * (-rot(0) * rot(1) + rot(2) * rot(3));
147 mat(2, 0) = 2 * (-rot(0) * rot(2) + rot(1) * rot(3));
148 mat(2, 1) = 2 * (rot(0) * rot(1) + rot(2) * rot(3));
149 mat(2, 2) = 1 - 2 * (rot(1) * rot(1) + rot(2) * rot(2));
150
151 return mat;
152}
Vector3D cross(const Vector3D &lhs, const Vector3D &rhs)
Vector cross product.
Definition Vector3D.cpp:111
double dot(const Vector3D &lhs, const Vector3D &rhs)
Vector dot product.
Definition Vector3D.cpp:118
Quaternion getQuaternion(Vector_t u, Vector_t ref)
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition TpsMath.h:91
boost::numeric::ublas::matrix< double > matrix_t
Definition BoostMatrix.h:23
RandomNumberGen IpplRandom
constexpr double pi
The value of.
Definition Physics.h:30
Quaternion & normalize()
Vector_t rotate(const Vector_t &) const
double real() const
Definition Quaternion.h:111
Quaternion conjugate() const
Definition Quaternion.h:103
Quaternion inverse() const
Quaternion & operator*=(const Quaternion &)
Quaternion operator/(const double &) const
Vector_t imag() const
Definition Quaternion.h:117
bool isUnit() const
Definition Quaternion.h:85
Quaternion operator*(const double &) const
matrix_t getRotationMatrix() const
double length() const
Definition Quaternion.h:79
double Norm() const
Definition Quaternion.h:73
Definition Vec.h:22
Vektor< double, 3 > Vector_t