#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 () |
Quaternion & | inverse () |
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 |
Quaternion & | operator+= (const Quaternion &q) |
Quaternion & | operator-= (const Quaternion &q) |
Quaternion & | operator *= (const Quaternion &q) |
Quaternion & | operator *= (float s) |
Quaternion & | operator/= (const Quaternion &q) |
Quaternion & | operator/= (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 |
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 65 of file quaternion.h.
Quaternion::Quaternion | ( | ) |
Quaternion::Quaternion | ( | float | e0, | |
float | e1, | |||
float | e2, | |||
float | e3 | |||
) |
Quaternion::Quaternion | ( | float | radians, | |
const Vec3f & | axis | |||
) |
Quaternion::Quaternion | ( | const Vec3f & | axis, | |
float | radians | |||
) |
Quaternion::Quaternion | ( | const vector< float > & | matrix3 | ) | [explicit] |
Definition at line 77 of file quaternion.cpp.
References e0, e1, e2, e3, and sqrt().
00078 { 00079 int i = 0; 00080 00081 if (m[0] > m[4]) { 00082 if (m[0] > m[8]) { 00083 i = 0; 00084 } 00085 else { 00086 i = 2; 00087 } 00088 } 00089 else { 00090 if (m[4] > m[8]) { 00091 i = 1; 00092 } 00093 else { 00094 i = 2; 00095 } 00096 } 00097 00098 if (m[0] + m[4] + m[8] > m[i*3+i]) { 00099 e0 = (float) (sqrt(m[0] + m[4] + m[8] + 1) / 2.0); 00100 e1 = (float) ((m[5] - m[7]) / (4 * e0)); 00101 e2 = (float) ((m[6] - m[2]) / (4 * e0)); 00102 e3 = (float) ((m[1] - m[3]) / (4 * e0)); 00103 } 00104 else { 00105 float quat[3]; 00106 int j = (i + 1) % 3; 00107 int k = (i + 2) % 3; 00108 00109 quat[i] = (float) (sqrt(m[i*3+i] - m[j*3+j] - m[k*3+k] + 1) / 2.0); 00110 quat[j] = (float) ((m[i*3+j] + m[j*3+i]) / (4 * quat[i])); 00111 quat[k] = (float) ((m[i*3+k] + m[k*3+i]) / (4 * quat[i])); 00112 00113 e0 = (float) ((m[j*3+k] - m[k*3+j]) / (4 * quat[i])); 00114 e1 = quat[0]; 00115 e2 = quat[1]; 00116 e3 = quat[2]; 00117 } 00118 00119 //normalize(); 00120 }
EMAN::Quaternion::~Quaternion | ( | ) | [inline] |
float EMAN::Quaternion::abs | ( | ) | const [inline] |
vector< float > Quaternion::as_list | ( | ) | const |
Quaternion EMAN::Quaternion::conj | ( | ) | const [inline] |
Definition at line 83 of file quaternion.h.
References Quaternion().
00084 { 00085 return (Quaternion(e0, -e1, -e2, -e3)); 00086 }
Quaternion Quaternion::create_inverse | ( | ) | const |
Definition at line 142 of file quaternion.cpp.
References q.
00143 { 00144 Quaternion q = *this; 00145 return q.inverse(); 00146 }
Quaternion Quaternion::interpolate | ( | const Quaternion & | from, | |
const Quaternion & | to, | |||
float | percent | |||
) | [static] |
Definition at line 376 of file quaternion.cpp.
References e0, e1, e2, e3, and q.
00378 { 00379 const double epsilon = 0.00001; 00380 double cosom = from.e1 * to.e1 + from.e2 * to.e2 + from.e3 * to.e3 + from.e0 * to.e0; 00381 00382 Quaternion q; 00383 if (cosom < 0) { 00384 cosom = -cosom; 00385 q = q - to; 00386 } 00387 else { 00388 q = to; 00389 } 00390 00391 double scale0 = 1 - t; 00392 double scale1 = t; 00393 00394 if ((1 - cosom) > epsilon) { 00395 double omega = acos(cosom); 00396 double sinom = sin(omega); 00397 scale0 = sin((1 - t) * omega) / sinom; 00398 scale1 = sin(t * omega) / sinom; 00399 } 00400 00401 float scale0f = (float) scale0; 00402 float scale1f = (float) scale1; 00403 00404 return (scale0f * from + scale1f * q); 00405 }
Quaternion & Quaternion::inverse | ( | ) |
float EMAN::Quaternion::norm | ( | ) | const [inline] |
void Quaternion::normalize | ( | ) |
Quaternion & Quaternion::operator *= | ( | float | s | ) |
Quaternion & Quaternion::operator *= | ( | const Quaternion & | q | ) |
Definition at line 251 of file quaternion.cpp.
References b, e0, e1, e2, e3, and q.
00252 { 00253 float a = e0 * q.e0 - e1 * q.e1 - e2 * q.e2 - e3 * q.e3; 00254 float b = e0 * q.e1 + e1 * q.e0 + e2 * q.e3 - e3 * q.e2; 00255 float c = e0 * q.e2 - e1 * q.e3 + e2 * q.e0 + e3 * q.e1; 00256 float d = e0 * q.e3 + e1 * q.e2 - e2 * q.e1 + e3 * q.e0; 00257 00258 e0 = a; 00259 e1 = b; 00260 e2 = c; 00261 e3 = d; 00262 00263 00264 // normalize(); 00265 00266 return (*this); 00267 }
Quaternion & Quaternion::operator+= | ( | const Quaternion & | q | ) |
Quaternion & Quaternion::operator-= | ( | const Quaternion & | q | ) |
Quaternion & Quaternion::operator/= | ( | float | s | ) |
Quaternion & Quaternion::operator/= | ( | const Quaternion & | q | ) |
Definition at line 278 of file quaternion.cpp.
References b, e0, e1, e2, e3, and q.
00279 { 00280 float qn = q.norm(); 00281 00282 float a = (+e0 * q.e0 + e1 * q.e1 + e2 * q.e2 + e3 * q.e3) / qn; 00283 float b = (-e0 * q.e1 + e1 * q.e0 - e2 * q.e3 + e3 * q.e2) / qn; 00284 float c = (-e0 * q.e2 + e1 * q.e3 + e2 * q.e0 - e3 * q.e1) / qn; 00285 float d = (-e0 * q.e3 - e1 * q.e2 + e2 * q.e1 + e3 * q.e0) / qn; 00286 00287 e0 = a; 00288 e1 = b; 00289 e2 = c; 00290 e3 = d; 00291 00292 return (*this); 00293 }
float Quaternion::real | ( | ) | const |
float Quaternion::to_angle | ( | ) | const |
Definition at line 160 of file quaternion.cpp.
References e0, e1, e2, e3, and q.
00161 { 00162 Vec3f q(e1, e2, e3); 00163 float len = q.length(); 00164 float radians = 0; 00165 00166 if (len > 0.00001f) { 00167 radians = 2.0f * acos(e0); 00168 } 00169 else { 00170 radians = 0; 00171 } 00172 return radians; 00173 }
Vec3f Quaternion::to_axis | ( | ) | const |
Definition at line 175 of file quaternion.cpp.
References e1, e2, e3, q, and EMAN::Vec3< Type >::set_value().
00176 { 00177 Vec3f q(e1, e2, e3); 00178 float len = q.length(); 00179 Vec3f axis; 00180 00181 if (len > 0.00001f) { 00182 axis = q * ((float) (1.0f / len)); 00183 } 00184 else { 00185 axis.set_value(0.0f, 0.0f, 1.0f); 00186 } 00187 return axis; 00188 }
vector< float > Quaternion::to_matrix3 | ( | ) | const |
Definition at line 191 of file quaternion.cpp.
References e0, e1, e2, and e3.
00192 { 00193 vector < float >m(9); 00194 00195 m[0] = e0 * e0 + e1 * e1 - e2 * e2 - e3 * e3; 00196 m[1] = 2.0f * (e1 * e2 + e0 * e3); 00197 m[2] = 2.0f * (e1 * e3 - e0 * e2); 00198 00199 m[3] = 2.0f * (e1 * e2 - e0 * e3); 00200 m[4] = e0 * e0 + e1 * e1 + e2 * e2 - e3 * e3; 00201 m[5] = 2.0f * (e2 * e3 + e0 * e1); 00202 00203 m[6] = 2.0f * (e1 * e3 + e0 * e2); 00204 m[7] = 2.0f * (e2 * e3 - e0 * e1); 00205 m[8] = e0 * e0 - e1 * e1 - e2 * e2 + e3 * e3; 00206 00207 return m; 00208 }
Vec3f Quaternion::unreal | ( | ) | const |
float EMAN::Quaternion::e0 [private] |
Definition at line 119 of file quaternion.h.
Referenced by as_list(), interpolate(), inverse(), normalize(), operator *=(), operator+=(), operator-=(), operator/=(), Quaternion(), real(), rotate(), to_angle(), and to_matrix3().
float EMAN::Quaternion::e1 [private] |
Definition at line 120 of file quaternion.h.
Referenced by as_list(), interpolate(), inverse(), normalize(), operator *=(), operator+=(), operator-=(), operator/=(), Quaternion(), rotate(), to_angle(), to_axis(), to_matrix3(), and unreal().
float EMAN::Quaternion::e2 [private] |
Definition at line 121 of file quaternion.h.
Referenced by as_list(), interpolate(), inverse(), normalize(), operator *=(), operator+=(), operator-=(), operator/=(), Quaternion(), rotate(), to_angle(), to_axis(), to_matrix3(), and unreal().
float EMAN::Quaternion::e3 [private] |
Definition at line 122 of file quaternion.h.
Referenced by as_list(), interpolate(), inverse(), normalize(), operator *=(), operator+=(), operator-=(), operator/=(), Quaternion(), rotate(), to_angle(), to_axis(), to_matrix3(), and unreal().