Sensor Scol plugin
Multi platform sensors for handled devices
Quaternion.h
1#ifndef _QUATERNION_H_
2#define _QUATERNION_H_
3
4#include <math.h>
5#include "Matrix4.h"
6#include "Matrix3x3d.h"
7
9{
10
11 public:
12
13 static const Quaternion ZERO;
14 static const Quaternion IDENTITY;
15
17 {
18 w = 1.0f;
19 x = 0.0f;
20 y = 0.0f;
21 z = 0.0f;
22 }
23
24 Quaternion(float ww, float xx, float yy, float zz)
25 {
26 w = ww;
27 x = xx;
28 y = yy;
29 z = zz;
30 }
31
32 //-----------------------------------------------------------------------
33 Quaternion operator+ (const Quaternion& rkQ) const
34 {
35 return Quaternion(w+rkQ.w,x+rkQ.x,y+rkQ.y,z+rkQ.z);
36 }
37 //-----------------------------------------------------------------------
38 Quaternion operator- (const Quaternion& rkQ) const
39 {
40 return Quaternion(w-rkQ.w,x-rkQ.x,y-rkQ.y,z-rkQ.z);
41 }
42 //-----------------------------------------------------------------------
43 Quaternion operator* (const Quaternion& rkQ) const
44 {
45 // NOTE: Multiplication is not generally commutative, so in most
46 // cases p*q != q*p.
47
48 return Quaternion
49 (
50 w * rkQ.w - x * rkQ.x - y * rkQ.y - z * rkQ.z,
51 w * rkQ.x + x * rkQ.w + y * rkQ.z - z * rkQ.y,
52 w * rkQ.y + y * rkQ.w + z * rkQ.x - x * rkQ.z,
53 w * rkQ.z + z * rkQ.w + x * rkQ.y - y * rkQ.x
54 );
55 }
56
57 Vector3d operator* (const Vector3d& v) const
58 {
59 Vector3d uv, uuv;
60 Vector3d qvec(x, y, z);
61 uv = qvec.CrossProduct(v);
62 uuv = qvec.CrossProduct(uv);
63 uv *= (2.0f * w);
64 uuv *= 2.0f;
65
66 return v + uv + uuv;
67 }
68
69 Quaternion Inverse () const
70 {
71 float fNorm = w*w+x*x+y*y+z*z;
72 if ( fNorm > 0.0 )
73 {
74 float fInvNorm = 1.0f/fNorm;
75 return Quaternion(w*fInvNorm,-x*fInvNorm,-y*fInvNorm,-z*fInvNorm);
76 }
77 else
78 {
79 // return an invalid result to flag the error
80 return Quaternion();
81 }
82 }
83
84 static Quaternion FromRotationMatrix(double* m)
85 {
86 float t = (float)(m[0] + m[5] + m[10]);
87 float s, w, x, y, z;
88 if (t >= 0.0f) {
89 s = sqrt(t + 1.0f);
90 w = 0.5f * s;
91 s = 0.5f / s;
92 x = (float)(m[9] - m[6]) * s;
93 y = (float)(m[2] - m[8]) * s;
94 z = (float)(m[4] - m[1]) * s;
95 }
96 else
97 {
98 if ((m[0] > m[5]) && (m[0] > m[10])) {
99 s = (float)sqrt(1.0f + m[0] - m[5] - m[10]);
100 x = s * 0.5f;
101 s = 0.5F / s;
102 y = (float)(m[4] + m[1]) * s;
103 z = (float)(m[2] + m[8]) * s;
104 w = (float)(m[9] - m[6]) * s;
105 }
106 else
107 {
108 if (m[5] > m[10]) {
109 s = (float)sqrt(1.0f + m[5] - m[0] - m[10]);
110 y = s * 0.5f;
111 s = 0.5f / s;
112 x = (float)(m[4] + m[1]) * s;
113 z = (float)(m[9] + m[6]) * s;
114 w = (float)(m[2] - m[8]) * s;
115 }
116 else {
117 s = (float)sqrt(1.0f + m[10] - m[0] - m[5]);
118 z = s * 0.5f;
119 s = 0.5f / s;
120 x = (float)(m[2] + m[8]) * s;
121 y = (float)(m[9] + m[6]) * s;
122 w = (float)(m[4] - m[1]) * s;
123 }
124 }
125 }
126
127 return Quaternion(w, x, y, z);
128 }
129
130 static Quaternion FromRotationMatrix(Matrix3x3d m)
131 {
132 double rotationMatrix[16];
133 for (int r = 0; r < 3; r++)
134 {
135 for (int c = 0; c < 3; c++)
136 {
137 rotationMatrix[(4 * c + r)] = m.get(r, c);
138 }
139 }
140 double tmp62_61 = (rotationMatrix[11] = 0.0); rotationMatrix[7] = tmp62_61; rotationMatrix[3] = tmp62_61;
141 double tmp86_85 = (rotationMatrix[14] = 0.0); rotationMatrix[13] = tmp86_85; rotationMatrix[12] = tmp86_85;
142
143 rotationMatrix[15] = 1.0;
144 return FromRotationMatrix(rotationMatrix);
145 }
146
156 double getRoll(bool reprojectAxis = true) const
157 {
158 if (reprojectAxis)
159 {
160 double fTy = 2.0f*y;
161 double fTz = 2.0f*z;
162 double fTwz = fTz*w;
163 double fTxy = fTy*x;
164 double fTyy = fTy*y;
165 double fTzz = fTz*z;
166
167 return atan2(fTxy+fTwz, 1.0f-(fTyy+fTzz));
168
169 }
170 else
171 {
172 return atan2(2*(x*y + w*z), w*w + x*x - y*y - z*z);
173 }
174 }
175
185 double getPitch(bool reprojectAxis = true) const
186 {
187 if (reprojectAxis)
188 {
189 double fTx = 2.0f*x;
190 double fTz = 2.0f*z;
191 double fTwx = fTx*w;
192 double fTxx = fTx*x;
193 double fTyz = fTz*y;
194 double fTzz = fTz*z;
195
196 return atan2(fTyz+fTwx, 1.0f-(fTxx+fTzz));
197 }
198 else
199 {
200 return atan2(2*(y*z + w*x), w*w - x*x - y*y + z*z);
201 }
202 }
203
213 double getYaw(bool reprojectAxis = true) const
214 {
215 if (reprojectAxis)
216 {
217 double fTx = 2.0f*x;
218 double fTy = 2.0f*y;
219 double fTz = 2.0f*z;
220 double fTwy = fTy*w;
221 double fTxx = fTx*x;
222 double fTxz = fTz*x;
223 double fTyy = fTy*y;
224
225 return atan2(fTxz+fTwy, 1.0f-(fTxx+fTyy));
226 }
227 else
228 {
229 return asin(-2*(x*z - w*y));
230 }
231 }
232
233 protected:
234 private:
235
236 public:
237 float x;
238 float y;
239 float z;
240 float w;
241 protected:
242 private:
243};
244
245#endif
double getRoll(bool reprojectAxis=true) const
Definition Quaternion.h:156
double getPitch(bool reprojectAxis=true) const
Definition Quaternion.h:185
double getYaw(bool reprojectAxis=true) const
Definition Quaternion.h:213