OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
Quaternion.cpp
Go to the documentation of this file.
2#include "AppTypes/Tenzor.h"
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 Tenzor<double, 3> mat(1 - 2 * (rot(2) * rot(2) + rot(3) * rot(3)),
140 2 * (-rot(0) * rot(3) + rot(1) * rot(2)),
141 2 * (rot(0) * rot(2) + rot(1) * rot(3)),
142 2 * (rot(0) * rot(3) + rot(1) * rot(2)),
143 1 - 2 * (rot(1) * rot(1) + rot(3) * rot(3)),
144 2 * (-rot(0) * rot(1) + rot(2) * rot(3)),
145 2 * (-rot(0) * rot(2) + rot(1) * rot(3)),
146 2 * (rot(0) * rot(1) + rot(2) * rot(3)),
147 1 - 2 * (rot(1) * rot(1) + rot(2) * rot(2)));
148
149 return mat;
150}
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)
Definition: Quaternion.cpp:34
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
Tps< T > sqrt(const Tps< T > &x)
Square root.
Definition: TpsMath.h:91
T::PETE_Expr_t::PETE_Return_t max(const PETE_Expr< T > &expr, NDIndex< D > &loc)
Definition: ReductionLoc.h:84
PETE_TBTree< FnCopysign, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > copysign(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
RandomNumberGen IpplRandom
constexpr double e
The value of.
Definition: Physics.h:39
constexpr double pi
The value of.
Definition: Physics.h:30
Quaternion & normalize()
Definition: Quaternion.cpp:102
Vector_t rotate(const Vector_t &) const
Definition: Quaternion.cpp:122
double real() const
Definition: Quaternion.h:113
Quaternion conjugate() const
Definition: Quaternion.h:105
Quaternion inverse() const
Definition: Quaternion.cpp:115
Tenzor< double, 3 > getRotationMatrix() const
Definition: Quaternion.cpp:135
Quaternion & operator*=(const Quaternion &)
Definition: Quaternion.cpp:84
Quaternion operator/(const double &) const
Definition: Quaternion.cpp:95
Vector_t imag() const
Definition: Quaternion.h:119
bool isUnit() const
Definition: Quaternion.h:87
Quaternion operator*(const double &) const
Definition: Quaternion.cpp:71
double length() const
Definition: Quaternion.h:81
double Norm() const
Definition: Quaternion.h:75
Definition: Vec.h:22
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6