raSystem  1.0 bata
raQuaternion.cpp
Go to the documentation of this file.
1 #include "..\include\raMain.h"
2 
3 namespace System
4 {
5 static float factorial(float p)
6 {
7  if ( p == 0.0f || p == 1.0f ) return 1.0f;
8  else if ( p < 0.0f ) return 0.0f;
9 
10  float f = 1.0f ;
11 
12  while( p > 1.0f )
13  {
14  f *= p ;
15  p-- ;
16  }
17 
18  return f;
19 }
21 {
22  float cos_z_2 = cosf(0.5f*(float)angles.z);
23  float cos_y_2 = cosf(0.5f*(float)angles.y);
24  float cos_x_2 = cosf(0.5f*(float)angles.x);
25 
26  float sin_z_2 = sinf(0.5f*(float)angles.z);
27  float sin_y_2 = sinf(0.5f*(float)angles.y);
28  float sin_x_2 = sinf(0.5f*(float)angles.x);
29 
30  // and now compute quaternion
31  s = cos_z_2*cos_y_2*cos_x_2 + sin_z_2*sin_y_2*sin_x_2;
32  v.x = cos_z_2*cos_y_2*sin_x_2 - sin_z_2*sin_y_2*cos_x_2;
33  v.y = cos_z_2*sin_y_2*cos_x_2 + sin_z_2*cos_y_2*sin_x_2;
34  v.z = sin_z_2*cos_y_2*cos_x_2 - cos_z_2*sin_y_2*sin_x_2;
35 }
36 raQuaternion::raQuaternion(float fs, float fx, float fy, float fz)
37 {
38  s = fs;
39  v = raVector3(fx, fy, fz);
40 }
42 {
43  s = pfs[0];
44  v = raVector3(pfs[1], pfs[2], pfs[3]);
45 }
47 {
48  (* this) = raQuaternionFromAxis(Angle, Axis);
49 }
51 {
52  (* this) = raQuaternionFromAxis(Angle, Axis);
53 }
55 {
56  float tmp = fabs(mat(1,1) + mat(2,2) + mat(3,3) + 1);
57  s = 0.5f*sqrt(tmp);
58 
59  if(s > 0.0000001f)
60  {
61  v.x = (mat.n[9]-mat.n[6])/(4*s);
62  v.y = (mat.n[2]-mat.n[8])/(4*s);
63  v.z = (mat.n[4]-mat.n[1])/(4*s);
64  }
65  else
66  {
67  // |w| <= 1/2
68  static int s_iNext[3] = { 2, 3, 1 };
69  int i = 1;
70  if ( mat(2,2) > mat(1,1) )
71  i = 2;
72  if ( mat(3,3) > mat(2,2) )
73  i = 3;
74  int j = s_iNext[i-1];
75  int k = s_iNext[j-1];
76 
77  float fRoot = sqrt(mat(i,i)-mat(j,j)-mat(k,k) + 1.0f);
78 
79  float *tmp[3] = { (float*)&v.x, (float*)&v.y, (float*)&v.z };
80  *tmp[i-1] = 0.5f*fRoot;
81  fRoot = 0.5f/fRoot;
82  s = (mat(k,j)-mat(j,k))*fRoot;
83  *tmp[j-1] = (mat(j,i)+mat(i,j))*fRoot;
84  *tmp[k-1] = (mat(k,i)+mat(i,k))*fRoot;
85  }
86 }
88 {
89  *this = *this * q;
90  return *this;
91 }
93 {
94  raQuaternion temp = q;
95  (* this) *= raQuaternionInvert(temp);
96  return *this;
97 }
99 {
100  s/=f; v.x/=f; v.y/=f; v.z/=f; return *this;
101 }
103 {
104  s*=f; v.x*=f; v.y*=f; v.z*=f; return *this;
105 }
107 {
108  float sinThetaOver2Sq = 1.0f - s*s;
109 
110  if (sinThetaOver2Sq <= 0.0f)
111  {
112  return raVector3(1.0f, 0.0f, 0.0f);
113  }
114 
115  // Compute 1 / sin(theta/2)
116 
117  float oneOverSinThetaOver2 = 1.0f / sqrt(sinThetaOver2Sq);
118 
119  // Return axis of rotation
120 
121  return raVector3(
122  (float)v.x * oneOverSinThetaOver2,
123  (float)v.y * oneOverSinThetaOver2,
124  (float)v.z * oneOverSinThetaOver2
125  );
126 }
128 {
129  float thetaOver2 = acos(s);
130  return thetaOver2 * 2.0f;
131 }
133 {
134  float Mul;
135 
136  raQuaternion temp(v);
137  float Length = raVector3Lenght(temp.v);
138 
139  if (Length > 1.0e-4)
140  Mul = sin(Length)/Length;
141  else
142  Mul = 1.0;
143 
144  temp.s = cos(Length);
145 
146  temp.v.x *= Mul;
147  temp.v.y *= Mul;
148  temp.v.z *= Mul;
149 
150  return temp;
151 }
153 {
154  float Length;
155  raQuaternion temp(v);
156 
157  Length = raVector3Lenght(temp.v);
158  Length = atan(Length/temp.s);
159 
160  temp.s = 0.0;
161 
162  temp.v.x *= Length;
163  temp.v.y *= Length;
164  temp.v.z *= Length;
165 
166  return temp;
167 }
169 {
170  float norme = raQuaternionLenght(v);
171  raQuaternion temp(v);
172 
173  if (norme == 0.0)
174  {
175  temp.s = 1.0f;
176  temp.v = 0.0f;
177  }
178  else
179  {
180  float recip = 1.0f/norme;
181 
182  temp.s *= recip;
183  temp.v.x *= recip;
184  temp.v.y *= recip;
185  temp.v.z *= recip;
186  }
187  return temp;
188 }
190 {
191  float omega, s, c;
192  raQuaternion temp;
193 
194  s = raVector3Lenght(Axis);
195 
196  if (fabs(s) > FLT_EPSILON)
197  {
198  c = 1.0f/s;
199 
200  Axis.x *= c;
201  Axis.y *= c;
202  Axis.z *= c;
203 
204  omega = -0.5f * Angle;
205  s = (float)sin(omega);
206 
207  temp.v = raVector3(s*(float)Axis.x, s*(float)Axis.y, s*(float)Axis.z);
208  temp.s = (float)cos(omega);
209  }
210  else
211  {
212  temp.v = raVector3(0.0f);
213  temp.s = 1.0f;
214  }
215  temp = raQuaternionNormalize(temp);
216  return temp;
217 }
219 {
220  return raMatrix(v.s, -v.v.x, -v.v.y, -v.v.z,
221  v.v.x, v.s, -v.v.z, v.v.y,
222  v.v.y, v.v.z, v.s, -v.v.x,
223  v.v.z, -v.v.y, v.v.x, v.s);
224 }
226 {
227  raQuaternion temp(v.v, v.s);
228 
229  temp.s = -temp.s;
230  temp.v = -temp.v;
231 
232  return temp;
233 }
235 {
236  raQuaternion z = a ;
237  return z /= b;
238 }
239 RAPI raQuaternion operator / (const raQuaternion& a, const float b)
240 {
241  raVector3 vt(a.v);
242  float ft(a.s);
243  vt /= b;
244  ft /= b;
245 
246  return raQuaternion(ft, vt);
247 }
248 RAPI raQuaternion operator / (const float a, const raQuaternion& b)
249 {
250  raVector3 vt(b.v);
251  float ft(b.s);
252  vt /= a;
253  ft /= a;
254 
255  return raQuaternion(ft, vt);
256 }
257 
258 RAPI raQuaternion operator * (const raQuaternion& a, const float b)
259 {
260  raQuaternion temp(a);
261  temp *= b ;
262 
263  return temp ;
264 }
265 RAPI raQuaternion operator * (const float a,const raQuaternion& b)
266 {
267  raQuaternion temp(b);
268  temp *= a ;
269 
270  return temp ;
271 }
273 {
274  raQuaternion qtmp;
275 
276  qtmp.s = ((a.s * b.s) - (float)(a.v.x * b.v.x) - (float)(a.v.y * b.v.z) - (float)(a.v.z * b.v.z));
277  qtmp.v.x = ((a.s * (float)b.v.x) + ((float)a.v.x * b.s) + ((float)a.v.y * (float)b.v.y) - ((float)a.v.z * (float)b.v.y));
278  qtmp.v.y = ((a.s * (float)b.v.y) - ((float)a.v.x * (float)b.v.z) + ((float)a.v.y * b.s) + ((float)a.v.z * (float)b.v.x));
279  qtmp.v.z = ((a.s * (float)b.v.z) + ((float)a.v.x * (float)b.v.y) - ((float)a.v.y * (float)b.v.x) + ((float)a.v.z * b.s));
280 
281  return qtmp;
282 }
284 {
285  raQuaternion at(a), bt(b);
286 
287  at += bt;
288  return at;
289 }
291 {
292  raQuaternion at(a), bt(b);
293 
294  at -= bt;
295  return at;
296 }
297 
299 {
300  return raQuaternion(-a.s, -a.v);
301 }
302 
304 {
305  if (t <= 0.0f) return q0;
306  if (t >= 1.0f) return q1;
307 
308  float cosOmega = raQuaternionDot(q0, q1);
309 
310  float q1w = q1.s;
311  float q1x = q1.v.x;
312  float q1y = q1.v.y;
313  float q1z = q1.v.z;
314  if (cosOmega < 0.0f) {
315  q1w = -q1w;
316  q1x = -q1x;
317  q1y = -q1y;
318  q1z = -q1z;
319  cosOmega = -cosOmega;
320  }
321 
322  assert(cosOmega < 1.1f);
323 
324  // Compute interpolation fraction, checking for quaternions
325  // almost exactly the same
326 
327  float k0, k1;
328  if (cosOmega > 0.9999f)
329  {
330  k0 = 1.0f-t;
331  k1 = t;
332  } else {
333  // Compute the sin of the angle using the
334  // trig identity sin^2(omega) + cos^2(omega) = 1
335 
336  float sinOmega = sqrt(1.0f - cosOmega*cosOmega);
337 
338  // Compute the angle from its sin and cosine
339 
340  float omega = atan2(sinOmega, cosOmega);
341 
342  // Compute inverse of denominator, so we only have
343  // to divide once
344 
345  float oneOverSinOmega = 1.0f / sinOmega;
346 
347  // Compute interpolation parameters
348 
349  k0 = sin((1.0f - t) * omega) * oneOverSinOmega;
350  k1 = sin(t * omega) * oneOverSinOmega;
351  }
352 
353  // Interpolate
354 
355  raQuaternion result;
356  result.v.x = k0*(float)q0.v.x + k1*q1x;
357  result.v.y = k0*(float)q0.v.y + k1*q1y;
358  result.v.z = k0*(float)q0.v.z + k1*q1z;
359  result.s = k0*q0.s + k1*q1w;
360 
361  // Return it
362 
363  return result;
364 }
366 {
367  if (fabs(v.s) > .9999f)
368  {
369  return v;
370  }
371 
372  // Erhalte halbe angle alpha (alpha = theta/2)
373  float alpha = acos(v.s);
374 
375  // Berechne neuen alpha Wert
376  float newAlpha = alpha * Exp;
377 
378  // Berechne neuen s wert
379  raQuaternion result;
380  result.s = cos(newAlpha);
381 
382  // Berechne neue xyz Werte
383 
384  float mult = sin(newAlpha) / sin(alpha);
385  result.v.x = (float)v.v.x * mult;
386  result.v.y = (float)v.v.y * mult;
387  result.v.z = (float)v.v.z * mult;
388 
389  return result;
390 }
392 {
393  return a.s*b.s + (float)a.v.x*(float)b.v.x + (float)a.v.y*(float)b.v.y + (float)a.v.z*(float)b.v.z;
394 }
396 {
397  float temp = raQuaternionLenghtSq(q);
398  raQuaternion tq = q;
399 
400  tq.s /= temp;
401  tq.v.x /= -temp;
402  tq.v.y /= -temp;
403  tq.v.z /= -temp;
404  return q; // Okay, same norm.
405 }
406 
408 {
409  if ( degree == 0 ) return raQuaternion(1.0f, 0.0f, 0.0f, 0.0f);
410 
411  raQuaternion tmp_qu = qu ;
412 
413  for ( float f = 1 ; f < abs(degree) ; f++ )
414  {
415  tmp_qu *= qu ;
416  }
417 
418  if ( degree < 0 ) return ( 1.0f / tmp_qu );
419 
420  return tmp_qu ;
421 }
423 {
424  raQuaternion s;
425 
426  for( float n = 0; n < 6.0f; n++ )
427  {
428  s += pow( -1.0f ,n ) * (raQuaternionPower( q , 2.0f * n + 1.0f ) ) / ( factorial( 2.0f * n + 1.0f ) );
429  }
430 
431  return s ;
432 }
434 {
435  raQuaternion s;
436 
437  for( float n = 1.0f; n <= 6.0f; n++ )
438  {
439  s += pow( -1.0f ,n ) * raQuaternionPower( q , 2.0f * n ) / factorial( 2.0f * n ) ;
440  }
441 
442  return s ;
443 }
445 {
446  if ( raQuaternionLenghtSq(q) == 0.0 ) return raQuaternion(1.0, 0.0, 0.0, 0.0) ;
447  return raQuaternionSin( q ) / raQuaternionCos( q ) ;
448 }
450 {
451  if ( raQuaternionLenghtSq(q) == 0.0 ) return raQuaternion(1.0, 0.0, 0.0, 0.0) ;
452  return raQuaternionCos( q ) / raQuaternionSin( q ) ;
453 }
454 };
float raQuaternionLenght(const raQuaternion &v)
Definition: raQuaternion.h:57
RAPI raQuaternion raQuaternionCos(const raQuaternion &q)
raFloat y
Definition: raVector3.h:13
RAPI raQuaternion raQuaternionSlerp(const raQuaternion &q0, const raQuaternion &q1, float t)
raFloat x
Definition: raVector3.h:12
raQuaternion & operator*=(const raQuaternion &q)
#define RAPI
Definition: raMain.h:11
RAPI raQuaternion raQuaternionInvert(const raQuaternion &q)
raQuaternion & operator/=(const raQuaternion &q)
RAPI float raQuaternionDot(const raQuaternion &a, const raQuaternion &b)
RAPI raQuaternion operator+(const raQuaternion &a, const raQuaternion &b)
RAPI raMatrix raQuaternionToMatrix(const raQuaternion &v)
raVector3 GetRotationAxis() const
RAPI raQuaternion raQuaternionExp(const raQuaternion &v)
float n[16]
Definition: raMatrix.h:19
RAPI raQuaternion raQuaternionNormalize(const raQuaternion &v)
raFloat z
Definition: raVector3.h:14
RAPI raQuaternion operator-(const raQuaternion &a, const raQuaternion &b)
RAPI raQuaternion raQuaternionPow(const raQuaternion &v, float Exp)
RAPI raQuaternion raQuaternionFromAxis(const float Angle, raVector3 Axis)
RAPI raQuaternion raQuaternionPower(const raQuaternion &qu, float degree)
RAPI raQuaternion raQuaternionLog(const raQuaternion &v)
raFloat raVector3Lenght(const raVector3 &v)
Definition: raVector3.h:59
RAPI raQuaternion raQuaternionConjugate(const raQuaternion &v)
float GetRotationAngle() const
RAPI raQuaternion operator*(const raQuaternion &a, const float b)
RAPI raQuaternion operator/(const raQuaternion &a, const raQuaternion &b)
float raQuaternionLenghtSq(const raQuaternion &v)
Definition: raQuaternion.h:58
RAPI raQuaternion raQuaternionCTan(const raQuaternion &q)
class RAPI raMatrix
Definition: raVector3.h:3
RAPI raQuaternion raQuaternionTan(const raQuaternion &q)
raVector3 v
Definition: raQuaternion.h:10
RAPI raQuaternion raQuaternionSin(const raQuaternion &q)