UtilsLite
Utilities for C++ programming
Loading...
Searching...
No Matches
Quaternion.hxx
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*\
2 | |
3 | Copyright (C) 2011 |
4 | |
5 | , __ , __ |
6 | /|/ \ /|/ \ |
7 | | __/ _ ,_ | __/ _ ,_ |
8 | | \|/ / | | | | \|/ / | | | |
9 | |(__/|__/ |_/ \_/|/|(__/|__/ |_/ \_/|/ |
10 | /| /| |
11 | \| \| |
12 | |
13 | Enrico Bertolazzi |
14 | Dipartimento di Ingegneria Industriale |
15 | Università degli Studi di Trento |
16 | email: enrico.bertolazzi@unitn.it |
17 | |
18\*--------------------------------------------------------------------------*/
19
20//
21// file: Quaternion.hxx
22//
23
24namespace Utils {
25
26 #ifndef DOXYGEN_SHOULD_SKIP_THIS
27 using std::ostream;
28 #endif
29
51 template <typename T>
52 class Quaternion {
53 public:
57 using real_type = T;
58
59 private:
60 real_type m_Q[4];
61
62 public:
63
68 m_Q[0] = m_Q[1] = m_Q[2] = m_Q[3] = 0;
69 }
70
80 real_type A,
81 real_type B,
82 real_type C,
83 real_type D
84 ) {
85 m_Q[0] = A;
86 m_Q[1] = B;
87 m_Q[2] = C;
88 m_Q[3] = D;
89 }
90
99 void
101 real_type A,
102 real_type B,
103 real_type C,
104 real_type D
105 ) {
106 m_Q[0] = A;
107 m_Q[1] = B;
108 m_Q[2] = C;
109 m_Q[3] = D;
110 }
111
117 void
118 print( ostream_type & os ) const {
119 os << "[ "
120 << m_Q[0] << ", "
121 << m_Q[1] << "i, "
122 << m_Q[2] << "j, "
123 << m_Q[3] << "k ]";
124 }
125
133 operator [] (int i) const { return m_Q[i]; }
134
144 void
145 conj() { m_Q[1] = -m_Q[1]; m_Q[2] = -m_Q[2]; m_Q[3] = -m_Q[3]; }
146
159 void
161 real_type bf = 1/(m_Q[0]*m_Q[0] + m_Q[1]*m_Q[1] + m_Q[2]*m_Q[2] + m_Q[3]*m_Q[3]);
162 m_Q[0] *= bf; bf = -bf; m_Q[1] *= bf; m_Q[2] *= bf; m_Q[3] *= bf;
163 }
164
175 norm() const {
176 return sqrt(m_Q[0]*m_Q[0] + m_Q[1]*m_Q[1] + m_Q[2]*m_Q[2] + m_Q[3]*m_Q[3]);
177 }
178
191 void
192 rotate( real_type const v[3], real_type w[3] ) const {
193 w[0] = ( m_Q[0] * m_Q[0] + m_Q[1] * m_Q[1] ) * v[0]
194 + ( m_Q[1] * m_Q[2] - m_Q[0] * m_Q[3] ) * v[1]
195 + ( m_Q[1] * m_Q[3] + m_Q[0] * m_Q[2] ) * v[2];
196
197 w[1] = ( m_Q[1] * m_Q[2] + m_Q[0] * m_Q[3] ) * v[0]
198 + ( m_Q[0] * m_Q[0] + m_Q[2] * m_Q[2] ) * v[1]
199 + ( m_Q[2] * m_Q[3] - m_Q[0] * m_Q[1] ) * v[2];
200
201 w[2] = ( m_Q[1] * m_Q[3] - m_Q[0] * m_Q[2] ) * v[0]
202 + ( m_Q[2] * m_Q[3] + m_Q[0] * m_Q[1] ) * v[1]
203 + ( m_Q[0] * m_Q[0] + m_Q[3] * m_Q[3] ) * v[2];
204
205 w[0] = 2*w[0] - v[0];
206 w[1] = 2*w[1] - v[1];
207 w[2] = 2*w[2] - v[2];
208 }
209
232 to_axis( real_type axis[3] ) const {
233 real_type sin_phi = sqrt( m_Q[1]*m_Q[1] + m_Q[2]*m_Q[2] + m_Q[3]*m_Q[3] );
234 real_type cos_phi = m_Q[0];
235 real_type angle = 2 * atan2( sin_phi, cos_phi );
236 if ( sin_phi == 0 ) {
237 axis[0] = 1; axis[1] = axis[2] = 0;
238 } else {
239 axis[0] = m_Q[1] / sin_phi;
240 axis[1] = m_Q[2] / sin_phi;
241 axis[2] = m_Q[3] / sin_phi;
242 }
243 return angle;
244 }
245
251 void
252 to_matrix( real_type mat[3][3] ) const {
253 real_type axis[3];
254 real_type angle = to_axis( axis );
255 real_type ca = cos( angle );
256 real_type sa = sin( angle );
257
258 mat[0][0] = axis[0] * axis[0] + ca * ( 1 - axis[0] * axis[0] );
259 mat[1][0] = ( 1 - ca ) * axis[0] * axis[1] - sa * axis[2];
260 mat[2][0] = ( 1 - ca ) * axis[0] * axis[2] + sa * axis[1];
261
262 mat[0][1] = ( 1 - ca ) * axis[1] * axis[0] + sa * axis[2];
263 mat[1][1] = axis[1] * axis[1] + ca * ( 1 - axis[1] * axis[1] );
264 mat[2][1] = ( 1 - ca ) * axis[1] * axis[2] - sa * axis[0];
265
266 mat[0][2] = ( 1 - ca ) * axis[2] * axis[0] - sa * axis[1];
267 mat[1][2] = ( 1 - ca ) * axis[2] * axis[1] + sa * axis[0];
268 mat[2][2] = axis[2] * axis[2] + ca * ( 1 - axis[2] * axis[2] );
269 }
270
271 };
272
295 template <typename T>
296 inline
297 Quaternion<T>
298 operator * ( Quaternion<T> const & a, Quaternion<T> const & b ) {
299 return Quaternion<T>( a[0] * b[0] - a[1] * b[1] - a[2] * b[2] - a[3] * b[3],
300 a[0] * b[1] + a[1] * b[0] + a[2] * b[3] - a[3] * b[2],
301 a[0] * b[2] - a[1] * b[3] + a[2] * b[0] + a[3] * b[1],
302 a[0] * b[3] + a[1] * b[2] - a[2] * b[1] + a[3] * b[0] );
303 }
304
312 template <typename T>
313 inline
315 Q.print(os);
316 return os;
317 }
318}
319
320//
321// eof: Quaternion.hxx
322//
Implement some operationn on quaternion.
Definition Quaternion.hxx:52
real_type norm() const
Definition Quaternion.hxx:175
real_type to_axis(real_type axis[3]) const
Definition Quaternion.hxx:232
void rotate(real_type const v[3], real_type w[3]) const
Definition Quaternion.hxx:192
T real_type
Definition Quaternion.hxx:57
void print(ostream_type &os) const
Definition Quaternion.hxx:118
Quaternion(real_type A, real_type B, real_type C, real_type D)
Definition Quaternion.hxx:79
void to_matrix(real_type mat[3][3]) const
Definition Quaternion.hxx:252
void invert()
Definition Quaternion.hxx:160
Quaternion()
Definition Quaternion.hxx:67
void setup(real_type A, real_type B, real_type C, real_type D)
Definition Quaternion.hxx:100
void conj()
Definition Quaternion.hxx:145
real_type operator[](int i) const
Definition Quaternion.hxx:133
Definition SystemUtils.cc:39
Quaternion< T > operator*(Quaternion< T > const &a, Quaternion< T > const &b)
Definition Quaternion.hxx:298
std::basic_ostream< char > ostream_type
Type for output stream.
Definition Console.hxx:28
ostream_type & operator<<(ostream_type &os, Quaternion< T > const &Q)
Definition Quaternion.hxx:314