OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimQuaternion.h
Go to the documentation of this file.
1 #ifndef ossimQuaternion_HEADER
2 #define ossimQuaternion_HEADER 1
7 class ossimMatrix4x4;
8 namespace ossim
9 {
10 
11 
14 {
15 
16  public:
17 
19 
20  value_type theVector[4]; // a four-vector
21 
22  inline Quaternion()
23  {
24  theVector[0]=0.0; theVector[1]=0.0; theVector[2]=0.0; theVector[3]=1.0;
25  }
26 
28  {
29  theVector[0]=x;
30  theVector[1]=y;
31  theVector[2]=z;
32  theVector[3]=w;
33  }
34 
35 /* inline Quaternion( const Vec4f& v ) */
36 /* { */
37 /* theVector[0]=v.x(); */
38 /* theVector[1]=v.y(); */
39 /* theVector[2]=v.z(); */
40 /* theVector[3]=v.w(); */
41 /* } */
42 
43 /* inline Quaternion( const Vec4d& v ) */
44 /* { */
45 /* theVector[0]=v.x(); */
46 /* theVector[1]=v.y(); */
47 /* theVector[2]=v.z(); */
48 /* theVector[3]=v.w(); */
49 /* } */
50 
51  inline Quaternion(ossim_float64 angle, const ossimDpt3d& axis)
52  {
53  makeRotate(angle,axis);
54  }
55  inline Quaternion(ossim_float64 angle, const ossimColumnVector3d& axis)
56  {
57  makeRotate(angle,axis);
58  }
59 /* inline Quaternion( value_type angle, const Vec3d& axis) */
60 /* { */
61 /* makeRotate(angle,axis); */
62 /* } */
63 
64 /* inline Quaternion( value_type angle1, const Vec3f& axis1, */
65 /* value_type angle2, const Vec3f& axis2, */
66 /* value_type angle3, const Vec3f& axis3) */
67 /* { */
68 /* makeRotate(angle1,axis1,angle2,axis2,angle3,axis3); */
69 /* } */
70 
71 /* inline Quaternion( value_type angle1, const Vec3d& axis1, */
72 /* value_type angle2, const Vec3d& axis2, */
73 /* value_type angle3, const Vec3d& axis3) */
74 /* { */
75 /* makeRotate(angle1,axis1,angle2,axis2,angle3,axis3); */
76 /* } */
77 
78  inline Quaternion& operator = (const Quaternion& v)
79  {
80  theVector[0]=v.theVector[0];
81  theVector[1]=v.theVector[1];
82  theVector[2]=v.theVector[2];
83  theVector[3]=v.theVector[3];
84  return *this;
85  }
86 
87  inline bool operator == (const Quaternion& v) const { return theVector[0]==v.theVector[0] && theVector[1]==v.theVector[1] && theVector[2]==v.theVector[2] && theVector[3]==v.theVector[3]; }
88 
89  inline bool operator != (const Quaternion& v) const { return theVector[0]!=v.theVector[0] || theVector[1]!=v.theVector[1] || theVector[2]!=v.theVector[2] || theVector[3]!=v.theVector[3]; }
90 
91  inline bool operator < (const Quaternion& v) const
92  {
93  if (theVector[0]<v.theVector[0]) return true;
94  else if (theVector[0]>v.theVector[0]) return false;
95  else if (theVector[1]<v.theVector[1]) return true;
96  else if (theVector[1]>v.theVector[1]) return false;
97  else if (theVector[2]<v.theVector[2]) return true;
98  else if (theVector[2]>v.theVector[2]) return false;
99  else return (theVector[3]<v.theVector[3]);
100  }
101 
102 
103  inline void set(value_type x, value_type y, value_type z, value_type w)
104  {
105  theVector[0]=x;
106  theVector[1]=y;
107  theVector[2]=z;
108  theVector[3]=w;
109  }
110 
111  void set(const ossimMatrix4x4& matrix);
112 
113  void get(ossimMatrix4x4& matrix) const;
114 
115 
116  inline value_type & operator [] (int i) { return theVector[i]; }
117  inline value_type operator [] (int i) const { return theVector[i]; }
118 
119  inline value_type & x() { return theVector[0]; }
120  inline value_type & y() { return theVector[1]; }
121  inline value_type & z() { return theVector[2]; }
122  inline value_type & w() { return theVector[3]; }
123 
124  inline value_type x() const { return theVector[0]; }
125  inline value_type y() const { return theVector[1]; }
126  inline value_type z() const { return theVector[2]; }
127  inline value_type w() const { return theVector[3]; }
128 
130  bool zeroRotation() const { return theVector[0]==0.0 && theVector[1]==0.0 && theVector[2]==0.0 && theVector[3]==1.0; }
131 
132 
133  /* -------------------------------------------------------------
134  BASIC ARITHMETIC METHODS
135  Implemented in terms of Vec4s. Some Vec4 operators, e.g.
136  operator* are not appropriate for quaternions (as
137  mathematical objects) so they are implemented differently.
138  Also define methods for conjugate and the multiplicative inverse.
139  ------------------------------------------------------------- */
141  inline const Quaternion operator * (value_type rhs) const
142  {
143  return Quaternion(theVector[0]*rhs, theVector[1]*rhs, theVector[2]*rhs, theVector[3]*rhs);
144  }
145 
147  inline Quaternion& operator *= (value_type rhs)
148  {
149  theVector[0]*=rhs;
150  theVector[1]*=rhs;
151  theVector[2]*=rhs;
152  theVector[3]*=rhs;
153  return *this; // enable nesting
154  }
155 
157  inline const Quaternion operator*(const Quaternion& rhs) const
158  {
159  return Quaternion( rhs.theVector[3]*theVector[0] + rhs.theVector[0]*theVector[3] + rhs.theVector[1]*theVector[2] - rhs.theVector[2]*theVector[1],
160  rhs.theVector[3]*theVector[1] - rhs.theVector[0]*theVector[2] + rhs.theVector[1]*theVector[3] + rhs.theVector[2]*theVector[0],
161  rhs.theVector[3]*theVector[2] + rhs.theVector[0]*theVector[1] - rhs.theVector[1]*theVector[0] + rhs.theVector[2]*theVector[3],
162  rhs.theVector[3]*theVector[3] - rhs.theVector[0]*theVector[0] - rhs.theVector[1]*theVector[1] - rhs.theVector[2]*theVector[2] );
163  }
164 
166  inline Quaternion& operator*=(const Quaternion& rhs)
167  {
168  value_type x = rhs.theVector[3]*theVector[0] + rhs.theVector[0]*theVector[3] + rhs.theVector[1]*theVector[2] - rhs.theVector[2]*theVector[1];
169  value_type y = rhs.theVector[3]*theVector[1] - rhs.theVector[0]*theVector[2] + rhs.theVector[1]*theVector[3] + rhs.theVector[2]*theVector[0];
170  value_type z = rhs.theVector[3]*theVector[2] + rhs.theVector[0]*theVector[1] - rhs.theVector[1]*theVector[0] + rhs.theVector[2]*theVector[3];
171  theVector[3] = rhs.theVector[3]*theVector[3] - rhs.theVector[0]*theVector[0] - rhs.theVector[1]*theVector[1] - rhs.theVector[2]*theVector[2];
172 
173  theVector[2] = z;
174  theVector[1] = y;
175  theVector[0] = x;
176 
177  return (*this); // enable nesting
178  }
179 
182  {
183  value_type div = 1.0/rhs;
184  return Quaternion(theVector[0]*div, theVector[1]*div, theVector[2]*div, theVector[3]*div);
185  }
186 
188  inline Quaternion& operator /= (value_type rhs)
189  {
190  value_type div = 1.0/rhs;
191  theVector[0]*=div;
192  theVector[1]*=div;
193  theVector[2]*=div;
194  theVector[3]*=div;
195  return *this;
196  }
197 
199  inline const Quaternion operator/(const Quaternion& denom) const
200  {
201  return ( (*this) * denom.inverse() );
202  }
203 
205  inline Quaternion& operator/=(const Quaternion& denom)
206  {
207  (*this) = (*this) * denom.inverse();
208  return (*this); // enable nesting
209  }
210 
212  inline const Quaternion operator + (const Quaternion& rhs) const
213  {
214  return Quaternion(theVector[0]+rhs.theVector[0], theVector[1]+rhs.theVector[1],
215  theVector[2]+rhs.theVector[2], theVector[3]+rhs.theVector[3]);
216  }
217 
219  inline Quaternion& operator += (const Quaternion& rhs)
220  {
221  theVector[0] += rhs.theVector[0];
222  theVector[1] += rhs.theVector[1];
223  theVector[2] += rhs.theVector[2];
224  theVector[3] += rhs.theVector[3];
225  return *this; // enable nesting
226  }
227 
229  inline const Quaternion operator - (const Quaternion& rhs) const
230  {
231  return Quaternion(theVector[0]-rhs.theVector[0], theVector[1]-rhs.theVector[1],
232  theVector[2]-rhs.theVector[2], theVector[3]-rhs.theVector[3] );
233  }
234 
236  inline Quaternion& operator -= (const Quaternion& rhs)
237  {
238  theVector[0]-=rhs.theVector[0];
239  theVector[1]-=rhs.theVector[1];
240  theVector[2]-=rhs.theVector[2];
241  theVector[3]-=rhs.theVector[3];
242  return *this; // enable nesting
243  }
244 
247  inline const Quaternion operator - () const
248  {
249  return Quaternion (-theVector[0], -theVector[1], -theVector[2], -theVector[3]);
250  }
251 
254  {
255  return std::sqrt( theVector[0]*theVector[0] + theVector[1]*theVector[1] + theVector[2]*theVector[2] + theVector[3]*theVector[3]);
256  }
257 
260  {
261  return theVector[0]*theVector[0] + theVector[1]*theVector[1] + theVector[2]*theVector[2] + theVector[3]*theVector[3];
262  }
263 
265  inline Quaternion conj () const
266  {
267  return Quaternion( -theVector[0], -theVector[1], -theVector[2], theVector[3] );
268  }
269 
271  inline const Quaternion inverse () const
272  {
273  return conj() / length2();
274  }
275 
276  /* --------------------------------------------------------
277  METHODS RELATED TO ROTATIONS
278  Set a quaternion which will perform a rotation of an
279  angle around the axis given by the vector (x,y,z).
280  Should be written to also accept an angle and a Vec3?
281 
282  Define Spherical Linear interpolation method also
283 
284  Not inlined - see the Quat.cpp file for implementation
285  -------------------------------------------------------- */
286  void makeRotate( value_type angle,
287  value_type x, value_type y, value_type z );
288  void makeRotate ( value_type angle, const ossimColumnVector3d& vec )
289  { makeRotate(angle, vec[0], vec[1], vec[2]);}
290  void makeRotate ( value_type angle, const ossimDpt3d& vec )
291  { makeRotate(angle, vec.x, vec.y, vec.z);}
292 
293  void makeRotate ( value_type angle1, const ossimColumnVector3d& axis1,
294  value_type angle2, const ossimColumnVector3d& axis2,
295  value_type angle3, const ossimColumnVector3d& axis3);
296  void makeRotate ( value_type angle1, const ossimDpt3d& axis1,
297  value_type angle2, const ossimDpt3d& axis2,
298  value_type angle3, const ossimDpt3d& axis3);
299 
305  void makeRotate( const ossimColumnVector3d& vec1, const ossimColumnVector3d& vec2 );
311  void makeRotate( const ossimDpt3d& vec1, const ossimDpt3d& vec2 );
312 
313 /* void makeRotate_original( const Vec3d& vec1, const Vec3d& vec2 ); */
314 
319  void getRotate ( value_type & angle, value_type & x, value_type & y, value_type & z ) const;
320 
325  void getRotate ( value_type& angle, ossimDpt3d& vec ) const
326  { getRotate(angle, vec.x, vec.y, vec.z);}
327 
328 
331  void slerp ( value_type t, const Quaternion& from, const Quaternion& to);
334  {
335  // nVidia SDK implementation
336  ossimDpt3d uv, uuv;
337  ossimDpt3d qvec(theVector[0], theVector[1], theVector[2]);
338  uv = qvec ^ v;
339  uuv = qvec ^ uv;
340  uv *= ( 2.0f * theVector[3] );
341  uuv *= 2.0f;
342  return v + uv + uuv;
343  }
344  friend ossimDpt3d operator *( const ossimDpt3d& lhs, const ossim::Quaternion& rhs)
345  {
346  ossimDpt3d uv, uuv;
347  ossimDpt3d qvec(rhs.theVector[0], rhs.theVector[1], rhs.theVector[2]);
348  uv = qvec ^ lhs;
349  uuv = qvec ^ uv;
350  uv *= ( 2.0f * rhs.theVector[3] );
351  uuv *= 2.0f;
352 
353  return lhs + uv + uuv;
354  }
355 
356 }; // end of class prototype
357 
358 } // end of namespace
359 
360 #endif
const Quaternion operator*(const Quaternion &rhs) const
Binary multiply.
ossim_uint32 x
value_type y() const
Quaternion(value_type x, value_type y, value_type z, value_type w)
value_type & x()
Quaternion(ossim_float64 angle, const ossimDpt3d &axis)
ossimRationalNumber operator-(ossim_int32 i, ossimRationalNumber &r)
value_type length() const
Length of the quaternion = sqrt( vec . vec )
const Quaternion operator/(const Quaternion &denom) const
Binary divide.
value_type x() const
bool operator!=(const ossimRefPtr< _Tp1 > &__a, const ossimRefPtr< _Tp2 > &__b) noexcept
Definition: ossimRefPtr.h:111
Quaternion & operator/=(const Quaternion &denom)
Unary divide.
ossim_uint32 y
A quaternion class.
This code was derived from https://gist.github.com/mshockwave.
Definition: Barrier.h:8
value_type & z()
ossimRationalNumber operator/(ossim_int32 i, ossimRationalNumber &r)
Quaternion conj() const
Conjugate.
value_type z() const
bool zeroRotation() const
return true if the Quaternion represents a zero rotation, and therefore can be ignored in computation...
ossimRationalNumber operator*(ossim_int32 i, ossimRationalNumber &r)
void makeRotate(value_type angle, const ossimColumnVector3d &vec)
double ossim_float64
bool operator<(const BaseMatrix &A, const BaseMatrix &)
Definition: newmat.h:1734
double z
Definition: ossimDpt3d.h:145
value_type length2() const
Length of the quaternion = vec . vec.
bool operator==(const ossimRefPtr< _Tp1 > &__a, const ossimRefPtr< _Tp2 > &__b) noexcept
Definition: ossimRefPtr.h:101
Quaternion & operator*=(const Quaternion &rhs)
Unary multiply.
value_type & w()
value_type w() const
ossim_float64 value_type
value_type & y()
void getRotate(value_type &angle, ossimDpt3d &vec) const
Return the angle and vector components represented by the quaternion.
#define OSSIM_DLL
void makeRotate(value_type angle, const ossimDpt3d &vec)
double x
Definition: ossimDpt3d.h:143
double y
Definition: ossimDpt3d.h:144
ossimRationalNumber operator+(ossim_int32 i, ossimRationalNumber &r)
const Quaternion inverse() const
Multiplicative inverse method: q^(-1) = q^*/(q.q^*)
Quaternion(ossim_float64 angle, const ossimColumnVector3d &axis)
value_type theVector[4]