EMAN2
Public Member Functions | Static Public Member Functions | Private Attributes | List of all members
EMAN::Quaternion Class Reference

Quaternion is used in Rotation and Transformation to replace Euler angles. More...

#include <quaternion.h>

Public Member Functions

 Quaternion ()
 
 Quaternion (float e0, float e1, float e2, float e3)
 
 Quaternion (float radians, const Vec3f &axis)
 
 Quaternion (const Vec3f &axis, float radians)
 
 Quaternion (const vector< float > &matrix3)
 
 ~Quaternion ()
 
float norm () const
 
Quaternion conj () const
 
float abs () const
 
void normalize ()
 
Quaternioninverse ()
 
Quaternion create_inverse () const
 
Vec3f rotate (const Vec3f &v) const
 
float to_angle () const
 
Vec3f to_axis () const
 
vector< float > to_matrix3 () const
 
float real () const
 
Vec3f unreal () const
 
vector< float > as_list () const
 
Quaternionoperator+= (const Quaternion &q)
 
Quaternionoperator-= (const Quaternion &q)
 
Quaternionoperator*= (const Quaternion &q)
 
Quaternionoperator*= (float s)
 
Quaternionoperator/= (const Quaternion &q)
 
Quaternionoperator/= (float s)
 

Static Public Member Functions

static Quaternion interpolate (const Quaternion &from, const Quaternion &to, float percent)
 

Private Attributes

float e0
 
float e1
 
float e2
 
float e3
 

Detailed Description

Quaternion is used in Rotation and Transformation to replace Euler angles.

Quaternions extend the concept of rotation in three dimensions to rotation in four dimensions. This avoids the problem of "gimbal-lock" and allows for the implementation of smooth and continuous rotation.

Euler angles have the disadvantage of being susceptible to "Gimbal lock" where attempts to rotate an object fail due to the order in which the rotations are performed.

Quaternions are a solution to this problem. Instead of rotating an object through a series of successive rotations, a quaternion allows the programmer to rotate an object through a single arbitary rotation axis.

Because the rotation axis is specifed as a unit direction vector, it may be calculated through vector mathematics or from spherical coordinates ie (longitude/latitude).

Quaternions offer another advantage in that they be interpolated. This allows for smooth and predictable rotation effects.

Definition at line 61 of file quaternion.h.

Constructor & Destructor Documentation

◆ Quaternion() [1/5]

Quaternion::Quaternion ( )

Definition at line 36 of file quaternion.cpp.

37: e0(0), e1(0), e2(0), e3(0)
38{
39}

Referenced by conj().

◆ Quaternion() [2/5]

Quaternion::Quaternion ( float  e0,
float  e1,
float  e2,
float  e3 
)

Definition at line 67 of file quaternion.cpp.

68:e0(ee0), e1(ee1), e2(ee2), e3(ee3)
69{
70 //normalize();
71}

◆ Quaternion() [3/5]

Quaternion::Quaternion ( float  radians,
const Vec3f axis 
)

Definition at line 41 of file quaternion.cpp.

42{
43 Vec3f q = axis;
44 //normalize();
45
46 q *= sin(radians / 2.0f);
47 e0 = cos(radians / 2.0f);
48
49 e1 = q[0];
50 e2 = q[1];
51 e3 = q[2];
52}

References e0, e1, e2, and e3.

◆ Quaternion() [4/5]

Quaternion::Quaternion ( const Vec3f axis,
float  radians 
)

Definition at line 54 of file quaternion.cpp.

55{
56 Vec3f q = axis;
57 //normalize();
58
59 q *= sin(radians / 2.0f);
60 e0 = cos(radians / 2.0f);
61
62 e1 = q[0];
63 e2 = q[1];
64 e3 = q[2];
65}

References e0, e1, e2, and e3.

◆ Quaternion() [5/5]

Quaternion::Quaternion ( const vector< float > &  matrix3)
explicit

Definition at line 73 of file quaternion.cpp.

74{
75 int i = 0;
76
77 if (m[0] > m[4]) {
78 if (m[0] > m[8]) {
79 i = 0;
80 }
81 else {
82 i = 2;
83 }
84 }
85 else {
86 if (m[4] > m[8]) {
87 i = 1;
88 }
89 else {
90 i = 2;
91 }
92 }
93
94 if (m[0] + m[4] + m[8] > m[i*3+i]) {
95 e0 = (float) (sqrt(m[0] + m[4] + m[8] + 1) / 2.0);
96 e1 = (float) ((m[5] - m[7]) / (4 * e0));
97 e2 = (float) ((m[6] - m[2]) / (4 * e0));
98 e3 = (float) ((m[1] - m[3]) / (4 * e0));
99 }
100 else {
101 float quat[3];
102 int j = (i + 1) % 3;
103 int k = (i + 2) % 3;
104
105 quat[i] = (float) (sqrt(m[i*3+i] - m[j*3+j] - m[k*3+k] + 1) / 2.0);
106 quat[j] = (float) ((m[i*3+j] + m[j*3+i]) / (4 * quat[i]));
107 quat[k] = (float) ((m[i*3+k] + m[k*3+i]) / (4 * quat[i]));
108
109 e0 = (float) ((m[j*3+k] - m[k*3+j]) / (4 * quat[i]));
110 e1 = quat[0];
111 e2 = quat[1];
112 e3 = quat[2];
113 }
114
115 //normalize();
116}
EMData * sqrt() const
return square root of current image

References e0, e1, e2, e3, and sqrt().

◆ ~Quaternion()

EMAN::Quaternion::~Quaternion ( )
inline

Definition at line 70 of file quaternion.h.

71 {
72 }

Member Function Documentation

◆ abs()

float EMAN::Quaternion::abs ( ) const
inline

Definition at line 84 of file quaternion.h.

85 {
86 return sqrt(norm());
87 }
float norm() const
Definition: quaternion.h:74

References norm(), and sqrt().

◆ as_list()

vector< float > Quaternion::as_list ( ) const

Definition at line 218 of file quaternion.cpp.

219{
220 vector < float >v(4);
221 v[0] = e0;
222 v[1] = e1;
223 v[2] = e2;
224 v[3] = e3;
225
226 return v;
227}

References e0, e1, e2, and e3.

Referenced by EMAN::operator==().

◆ conj()

Quaternion EMAN::Quaternion::conj ( ) const
inline

Definition at line 79 of file quaternion.h.

80 {
81 return (Quaternion(e0, -e1, -e2, -e3));
82 }

References e0, e1, e2, e3, and Quaternion().

◆ create_inverse()

Quaternion Quaternion::create_inverse ( ) const

Definition at line 138 of file quaternion.cpp.

139{
140 Quaternion q = *this;
141 return q.inverse();
142}
Quaternion is used in Rotation and Transformation to replace Euler angles.
Definition: quaternion.h:62
Quaternion & inverse()
Definition: quaternion.cpp:128

References inverse().

◆ interpolate()

Quaternion Quaternion::interpolate ( const Quaternion from,
const Quaternion to,
float  percent 
)
static

Definition at line 372 of file quaternion.cpp.

374{
375 const double epsilon = 0.00001;
376 double cosom = from.e1 * to.e1 + from.e2 * to.e2 + from.e3 * to.e3 + from.e0 * to.e0;
377
378 Quaternion q;
379 if (cosom < 0) {
380 cosom = -cosom;
381 q = q - to;
382 }
383 else {
384 q = to;
385 }
386
387 double scale0 = 1 - t;
388 double scale1 = t;
389
390 if ((1 - cosom) > epsilon) {
391 double omega = acos(cosom);
392 double sinom = sin(omega);
393 scale0 = sin((1 - t) * omega) / sinom;
394 scale1 = sin(t * omega) / sinom;
395 }
396
397 float scale0f = (float) scale0;
398 float scale1f = (float) scale1;
399
400 return (scale0f * from + scale1f * q);
401}

References e0, e1, e2, and e3.

◆ inverse()

Quaternion & Quaternion::inverse ( )

Definition at line 128 of file quaternion.cpp.

129{
130 float f = 1.0f / norm();
131 e0 *= f;
132 e1 *= -f;
133 e2 *= -f;
134 e3 *= -f;
135 return (*this);
136}

References e0, e1, e2, e3, and norm().

Referenced by create_inverse().

◆ norm()

float EMAN::Quaternion::norm ( ) const
inline

Definition at line 74 of file quaternion.h.

75 {
76 return (e0 * e0 + e1 * e1 + e2 * e2 + e3 * e3);
77 }

References e0, e1, e2, and e3.

Referenced by abs(), inverse(), normalize(), and operator/=().

◆ normalize()

void Quaternion::normalize ( )

Definition at line 119 of file quaternion.cpp.

120{
121 float dist = 1.0f / sqrt(norm());
122 e0 *= dist;
123 e1 *= dist;
124 e2 *= dist;
125 e3 *= dist;
126}

References e0, e1, e2, e3, norm(), and sqrt().

◆ operator*=() [1/2]

Quaternion & Quaternion::operator*= ( const Quaternion q)

Definition at line 247 of file quaternion.cpp.

248{
249 float a = e0 * q.e0 - e1 * q.e1 - e2 * q.e2 - e3 * q.e3;
250 float b = e0 * q.e1 + e1 * q.e0 + e2 * q.e3 - e3 * q.e2;
251 float c = e0 * q.e2 - e1 * q.e3 + e2 * q.e0 + e3 * q.e1;
252 float d = e0 * q.e3 + e1 * q.e2 - e2 * q.e1 + e3 * q.e0;
253
254 e0 = a;
255 e1 = b;
256 e2 = c;
257 e3 = d;
258
259
260 // normalize();
261
262 return (*this);
263}

References e0, e1, e2, and e3.

◆ operator*=() [2/2]

Quaternion & Quaternion::operator*= ( float  s)

Definition at line 265 of file quaternion.cpp.

266{
267 e0 *= s;
268 e1 *= s;
269 e2 *= s;
270 e3 *= s;
271 return (*this);
272}

References e0, e1, e2, and e3.

◆ operator+=()

Quaternion & Quaternion::operator+= ( const Quaternion q)

Definition at line 229 of file quaternion.cpp.

230{
231 e0 += q.e0;
232 e1 += q.e1;
233 e2 += q.e2;
234 e3 += q.e3;
235 return *this;
236}

References e0, e1, e2, and e3.

◆ operator-=()

Quaternion & Quaternion::operator-= ( const Quaternion q)

Definition at line 238 of file quaternion.cpp.

239{
240 e0 -= q.e0;
241 e1 -= q.e1;
242 e2 -= q.e2;
243 e3 -= q.e3;
244 return *this;
245}

References e0, e1, e2, and e3.

◆ operator/=() [1/2]

Quaternion & Quaternion::operator/= ( const Quaternion q)

Definition at line 274 of file quaternion.cpp.

275{
276 float qn = q.norm();
277
278 float a = (+e0 * q.e0 + e1 * q.e1 + e2 * q.e2 + e3 * q.e3) / qn;
279 float b = (-e0 * q.e1 + e1 * q.e0 - e2 * q.e3 + e3 * q.e2) / qn;
280 float c = (-e0 * q.e2 + e1 * q.e3 + e2 * q.e0 - e3 * q.e1) / qn;
281 float d = (-e0 * q.e3 - e1 * q.e2 + e2 * q.e1 + e3 * q.e0) / qn;
282
283 e0 = a;
284 e1 = b;
285 e2 = c;
286 e3 = d;
287
288 return (*this);
289}

References e0, e1, e2, e3, and norm().

◆ operator/=() [2/2]

Quaternion & Quaternion::operator/= ( float  s)

Definition at line 291 of file quaternion.cpp.

292{
293 if (s != 0) {
294 e0 /= s;
295 e1 /= s;
296 e2 /= s;
297 e3 /= s;
298 }
299
300 return (*this);
301}

References e0, e1, e2, and e3.

◆ real()

float Quaternion::real ( ) const

Definition at line 208 of file quaternion.cpp.

209{
210 return e0;
211}

References e0.

◆ rotate()

Vec3f Quaternion::rotate ( const Vec3f v) const

Definition at line 145 of file quaternion.cpp.

146{
147 Vec3f i(e1, e2, e3);
148 Vec3f v1 = i.cross(v) * (2 * e0);
149 Vec3f v2 = v1.cross(i) * (float) 2;
150 Vec3f rotated = v + v1 - v2;
151
152 return rotated;
153}
Vec3< Type > cross(const Vec3< Type2 > &v) const
Calculate the cross product of 'this' vector with a second vector.
Definition: vec3.h:384

References EMAN::Vec3< Type >::cross(), e0, e1, e2, and e3.

◆ to_angle()

float Quaternion::to_angle ( ) const

Definition at line 156 of file quaternion.cpp.

157{
158 Vec3f q(e1, e2, e3);
159 float len = q.length();
160 float radians = 0;
161
162 if (len > 0.00001f) {
163 radians = 2.0f * acos(e0);
164 }
165 else {
166 radians = 0;
167 }
168 return radians;
169}

References e0, e1, e2, e3, and EMAN::Vec3< Type >::length().

◆ to_axis()

Vec3f Quaternion::to_axis ( ) const

Definition at line 171 of file quaternion.cpp.

172{
173 Vec3f q(e1, e2, e3);
174 float len = q.length();
175 Vec3f axis;
176
177 if (len > 0.00001f) {
178 axis = q * ((float) (1.0f / len));
179 }
180 else {
181 axis.set_value(0.0f, 0.0f, 1.0f);
182 }
183 return axis;
184}
void set_value(const vector< Type2 > &v)
Set new values using a std::vector object.
Definition: vec3.h:408

References e1, e2, e3, EMAN::Vec3< Type >::length(), and EMAN::Vec3< Type >::set_value().

◆ to_matrix3()

vector< float > Quaternion::to_matrix3 ( ) const

Definition at line 187 of file quaternion.cpp.

188{
189 vector < float >m(9);
190
191 m[0] = e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3;
192 m[1] = 2.0f * (e1 * e2 + e0 * e3);
193 m[2] = 2.0f * (e1 * e3 - e0 * e2);
194
195 m[3] = 2.0f * (e1 * e2 - e0 * e3);
196 m[4] = e0 * e0 + e1 * e1 + e2 * e2 - e3 * e3;
197 m[5] = 2.0f * (e2 * e3 + e0 * e1);
198
199 m[6] = 2.0f * (e1 * e3 + e0 * e2);
200 m[7] = 2.0f * (e2 * e3 - e0 * e1);
201 m[8] = e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3;
202
203 return m;
204}

References e0, e1, e2, and e3.

◆ unreal()

Vec3f Quaternion::unreal ( ) const

Definition at line 213 of file quaternion.cpp.

214{
215 return Vec3f(e1, e2, e3);
216}
Vec3< float > Vec3f
Definition: vec3.h:693

References e1, e2, and e3.

Member Data Documentation

◆ e0

float EMAN::Quaternion::e0
private

◆ e1

float EMAN::Quaternion::e1
private

◆ e2

float EMAN::Quaternion::e2
private

◆ e3

float EMAN::Quaternion::e3
private

The documentation for this class was generated from the following files: