JunkBox_Lib++ (for Windows) 1.10.1
Loading...
Searching...
No Matches
Rotation.h
Go to the documentation of this file.
1#ifndef __JBXL_CPP_QUATERNION_H_
2#define __JBXL_CPP_QUATERNION_H_
3
10#include "Matrix++.h"
11#include "Vector.h"
12
13
14//
15namespace jbxl {
16
17
19// クォータニオン
20//
21
22template <typename T> class DllExport Quaternion;
23
24// Q -> E
25template <typename T> Vector<T> Quaternion2ExtEulerXYZ(Quaternion<T> qut, Vector<T>* vct=NULL);
26template <typename T> Vector<T> Quaternion2ExtEulerZYX(Quaternion<T> qut, Vector<T>* vct=NULL);
27template <typename T> Vector<T> Quaternion2ExtEulerXZY(Quaternion<T> qut, Vector<T>* vct=NULL);
28template <typename T> Vector<T> Quaternion2ExtEulerYZX(Quaternion<T> qut, Vector<T>* vct=NULL);
29template <typename T> Vector<T> Quaternion2ExtEulerYXZ(Quaternion<T> qut, Vector<T>* vct=NULL);
30template <typename T> Vector<T> Quaternion2ExtEulerZXY(Quaternion<T> qut, Vector<T>* vct=NULL);
31
32
33
35
43template <typename T=double> class DllExport Quaternion
44{
45public:
46 T s;
47 T x;
48 T y;
49 T z;
50
51 T n;
52 T c;
53
54public:
55 Quaternion(void) { init();}
56 Quaternion(T S, T X, T Y, T Z, T N=(T)0.0, T C=(T)1.0) { set(S, X, Y, Z, N, C);}
57 Quaternion(T S, Vector<T> v) { setRotation(S, v);}
58 virtual ~Quaternion(void) {}
59
60 T norm(void) { n = (T)sqrt(s*s+x*x+y*y+z*z); return n;}
61 void normalize(void);
62
63 void set(T S, T X, T Y, T Z, T N=(T)0.0, T C=(T)1.0);
64 void init(T C=(T)1.0) { s=n=(T)1.0; x=y=z=(T)0.0; c=C;}
65
66 Vector<T> getVector() { Vector<T> v(x, y, z, (T)0.0, c); return v;}
67 T getScalar() { return s;}
68 T getAngle() { return (T)(2.0*acos(s));}
69 T getMathAngle() { T t=(T)(2.0*acos(s)); if(t>(T)PI)t-=(T)PI2; return t;}
70
72
73 void setRotation(T e, Vector<T> v);
74 void setRotation(T e, T X, T Y, T Z, T N=(T)0.0) { Vector<T> v(X, Y, Z, N); setRotation(e, v);}
75
76 void setRotate(T e, Vector<T> v) { setRotation(e, v);}
77 void setRotate(T e, T X, T Y, T Z, T N=(T)0.0) { Vector<T> v(X, Y, Z, N); setRotation(e, v);}
78
79 // 注:eの成分は演算順
86
87 Vector<T> getExtEulerXYZ(Vector<T>* vt=NULL) { return Quaternion2ExtEulerXYZ<T>(*this, vt);}
88 Vector<T> getExtEulerZYX(Vector<T>* vt=NULL) { return Quaternion2ExtEulerZYX<T>(*this, vt);}
89 Vector<T> getExtEulerXZY(Vector<T>* vt=NULL) { return Quaternion2ExtEulerXZY<T>(*this, vt);}
90 Vector<T> getExtEulerYZX(Vector<T>* vt=NULL) { return Quaternion2ExtEulerYZX<T>(*this, vt);}
91 Vector<T> getExtEulerYXZ(Vector<T>* vt=NULL) { return Quaternion2ExtEulerYXZ<T>(*this, vt);}
92 Vector<T> getExtEulerZXY(Vector<T>* vt=NULL) { return Quaternion2ExtEulerZXY<T>(*this, vt);}
93
96 Vector<T> execRotate(Vector<T> v) { return execRotation(v);}
97 Vector<T> execInvRotate(Vector<T> v) { return execInvRotation(v);}
98};
99
100
101
103// Quaternion オペレータ
104
105template <typename T> inline bool operator == (const Quaternion<T> q1, const Quaternion<T> q2)
106{ return (q1.s==q2.s && q1.x==q2.x && q1.y==q2.y && q1.z==q2.z); }
107
108
109template <typename T> inline bool operator != (const Quaternion<T> q1, const Quaternion<T> q2)
110{ return (q1.s!=q2.s || q1.x!=q2.x || q1.y!=q2.y || q1.z!=q2.z); }
111
112
114template <typename T> inline Quaternion<T> operator ~ (const Quaternion<T> a)
115{ return Quaternion<T>(a.s, -a.x, -a.y, -a.z, a.n, a.c); }
116
117
118//
119template <typename T> inline Quaternion<T> operator - (const Quaternion<T> a)
120{ return Quaternion<T>(-a.s, -a.x, -a.y, -a.z, a.n, a.c); }
121
122
123template <typename T> inline Quaternion<T> operator + (const Quaternion<T> a, const Quaternion<T> b)
124{ return Quaternion<T>(a.s+b.s, a.x+b.x, a.y+b.y, a.z+b.z, (T)0.0, Min(a.c, b.c)); }
125
126
127template <typename T> inline Quaternion<T> operator - (const Quaternion<T> a, const Quaternion<T> b)
128{ return Quaternion<T>(a.s-b.s, a.x-b.x, a.y-b.y, a.z-b.z, (T)0.0, Min(a.c, b.c)); }
129
130
131template <typename T, typename R> inline Quaternion<T> operator * (const R d, const Quaternion<T> a)
132{ return Quaternion<T>((T)d*a.s, (T)d*a.x, (T)d*a.y, (T)d*a.z, (T)d*a.n, a.c); }
133
134
135template <typename T, typename R> inline Quaternion<T> operator * (const Quaternion<T> a, const R d)
136{ return Quaternion<T>(a.s*(T)d, a.x*(T)d, a.y*(T)d, a.z*(T)d, a.n*(T)d, a.c); }
137
138
139template <typename T, typename R> inline Quaternion<T> operator / (const Quaternion<T> a, const R d)
140{ return Quaternion<T>(a.s/(T)d, a.x/(T)d, a.y/(T)d, a.z/(T)d, a.n/(T)d, a.c); }
141
142
146template <typename T> inline Quaternion<T> operator * (const Quaternion<T> a, const Quaternion<T> b)
147{
148 Quaternion<T> quat;
149 if (a.c<(T)0.0 || b.c<(T)0.0) quat.init(-(T)1.0);
150 else quat.set(a.s*b.s-a.x*b.x-a.y*b.y-a.z*b.z, a.s*b.x+a.x*b.s+a.y*b.z-a.z*b.y,
151 a.s*b.y+a.y*b.s+a.z*b.x-a.x*b.z, a.s*b.z+a.z*b.s+a.x*b.y-a.y*b.x, (T)1.0, Min(a.c, b.c));
152 return quat;
153}
154
155
156// *
157template <typename T> inline Quaternion<T> operator * (const Quaternion<T> q, const Vector<T> v)
158{
159 Quaternion<T> quat;
160 if (q.c<(T)0.0 || v.c<(T)0.0) quat.init(-(T)1.0);
161 else quat.set(-q.x*v.x-q.y*v.y-q.z*v.z, q.s*v.x+q.y*v.z-q.z*v.y,
162 q.s*v.y+q.z*v.x-q.x*v.z, q.s*v.z+q.x*v.y-q.y*v.x, v.n, Min(q.c, v.c));
163 return quat;
164}
165
166
167// *
168template <typename T> inline Quaternion<T> operator * (const Vector<T> v, const Quaternion<T> q)
169{
170 Quaternion<T> quat;
171 if (q.c<(T)0.0 || v.c<(T)0.0) quat.init(-(T)1.0);
172 else quat.set(-v.x*q.x-v.y*q.y-v.z*q.z, v.x*q.s+v.y*q.z-v.z*q.y,
173 v.y*q.s+v.z*q.x-v.x*q.z, v.z*q.s+v.x*q.y-v.y*q.x, (T)v.n, (T)Min(v.c, q.c));
174 return quat;
175}
176
177
178
180// 回転行列,オイラー角,クォータニオン
181//
182// 注:オイラー角ベクトルの成分は演算順に指定する.
183// 例 YZX回転なら e.x:Y回転,e.y:Z回転, e.z:X回転
184// オイラー角の回転は固定座標での計算(点,ベクトルの計算)
185//
186
187// E -> R
188/*
189template <typename T=double> Matrix<T> ExtEulerXYZ2RotMatrix(Vector<T> eul);
190template <typename T=double> Matrix<T> ExtEulerZYX2RotMatrix(Vector<T> eul);
191template <typename T=double> Matrix<T> ExtEulerXZY2RotMatrix(Vector<T> eul);
192template <typename T=double> Matrix<T> ExtEulerYZX2RotMatrix(Vector<T> eul);
193template <typename T=double> Matrix<T> ExtEulerYXZ2RotMatrix(Vector<T> eul);
194template <typename T=double> Matrix<T> ExtEulerZXY2RotMatrix(Vector<T> eul);
195*/
196
197
198// R -> E
199/*
200template <typename T=double> Vector<T> RotMatrix2ExtEulerXYZ(Matrix<T> mtx, Vector<T>* vct=NULL);
201template <typename T=double> Vector<T> RotMatrix2ExtEulerZYX(Matrix<T> mtx, Vector<T>* vct=NULL);
202template <typename T=double> Vector<T> RotMatrix2ExtEulerXZY(Matrix<T> mtx, Vector<T>* vct=NULL);
203template <typename T=double> Vector<T> RotMatrix2ExtEulerYZX(Matrix<T> mtx, Vector<T>* vct=NULL);
204template <typename T=double> Vector<T> RotMatrix2ExtEulerYXZ(Matrix<T> mtx, Vector<T>* vct=NULL);
205template <typename T=double> Vector<T> RotMatrix2ExtEulerZXY(Matrix<T> mtx, Vector<T>* vct=NULL);
206
207template <typename T=double> Vector<T> RotMatrixElements2ExtEulerXYZ(T m11, T m12, T m13, T m21, T m31, T m32, T m33, Vector<T>* vct=NULL);
208template <typename T=double> Vector<T> RotMatrixElements2ExtEulerZYX(T m11, T m12, T m13, T m21, T m23, T m31, T m33, Vector<T>* vct=NULL);
209template <typename T=double> Vector<T> RotMatrixElements2ExtEulerXZY(T m11, T m12, T m13, T m21, T m22, T m23, T m31, Vector<T>* vct=NULL);
210template <typename T=double> Vector<T> RotMatrixElements2ExtEulerYZX(T m11, T m12, T m13, T m21, T m22, T m31, T m32, Vector<T>* vct=NULL);
211template <typename T=double> Vector<T> RotMatrixElements2ExtEulerYXZ(T m12, T m21, T m22, T m23, T m31, T m32, T m33, Vector<T>* vct=NULL);
212template <typename T=double> Vector<T> RotMatrixElements2ExtEulerZXY(T m12, T m13, T m21, T m22, T m23, T m32, T m33, Vector<T>* vct=NULL);
213*/
214
215
216// Q -> E
217/*
218template <typename T=double> Vector<T> Quaternion2ExtEulerXYZ(Quaternion<T> qut, Vector<T>* vct=NULL);
219template <typename T=double> Vector<T> Quaternion2ExtEulerZYX(Quaternion<T> qut, Vector<T>* vct=NULL);
220template <typename T=double> Vector<T> Quaternion2ExtEulerXZY(Quaternion<T> qut, Vector<T>* vct=NULL);
221template <typename T=double> Vector<T> Quaternion2ExtEulerYZX(Quaternion<T> qut, Vector<T>* vct=NULL);
222template <typename T=double> Vector<T> Quaternion2ExtEulerYXZ(Quaternion<T> qut, Vector<T>* vct=NULL);
223template <typename T=double> Vector<T> Quaternion2ExtEulerZXY(Quaternion<T> qut, Vector<T>* vct=NULL);
224*/
225
226
227// R -> Q
228//template <typename T=double> Quaternion<T> RotMatrix2Quaternion<T>(Matrix<T> mtx);
229
230
231// Q -> R
232#define Quaternion2RotMatrix(q) (q).getRotMatrix()
233
234
235// E -> Q (注:eの成分は演算順)
236template <typename T> inline Quaternion<T> ExtEulerXYZ2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerXYZ(e); return q;}
237template <typename T> inline Quaternion<T> ExtEulerZYX2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerZYX(e); return q;}
238template <typename T> inline Quaternion<T> ExtEulerXZY2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerXZY(e); return q;}
239template <typename T> inline Quaternion<T> ExtEulerYZX2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerYZX(e); return q;}
240template <typename T> inline Quaternion<T> ExtEulerYXZ2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerYXZ(e); return q;}
241template <typename T> inline Quaternion<T> ExtEulerZXY2Quaternion(Vector<T> e) { Quaternion<T> q; q.setExtEulerZXY(e); return q;}
242
243
244
246// ベクトルの回転,クォータニオン
247//
248
249//template <typename T=double> Vector<T> VectorRotation<T>(Vector<T> v, Quaternion<T> q); // たぶん execRotation() よりは高速.
250//template <typename T=double> Vector<T> VectorInvRotation<T>(Vector<T> v, Quaternion<T> q);
251//template <typename T=double> T* VectorRotation<T>(T* v, Quaternion<T> q);
252//template <typename T=double> T* VectorInvRotation<T>(T* v, Quaternion<T> q);
253#define VectorRotate(v, q) VectorRotation((v),(q))
254#define VectorInvRotate(v, q) VectorInvRotation((v), (q))
255
256/*
257template <typename T=double> Quaternion<T> V2VQuaternion(Vector<T> a, Vector<T> b);
258
259template <typename T=double> Quaternion<T> PPPQuaternion(Vector<T> a, Vector<T> b, Vector<T> c);
260template <typename T=double> Quaternion<T> VPPQuaternion(Vector<T> a, Vector<T> b, Vector<T> c);
261template <typename T=double> Quaternion<T> PPVQuaternion(Vector<T> a, Vector<T> b, Vector<T> c);
262
263
264template <typename T=double> Quaternion<T> SlerpQuaternion(Quaternion<T> a, Quaternion<T> b, T t);
265*/
266
267
268
270// クォータニオン クラス
271//
272
273template <typename T> void Quaternion<T>::set(T S, T X, T Y, T Z, T N, T C)
274{
275 s = S;
276 x = X;
277 y = Y;
278 z = Z;
279 n = N;
280 c = C;
281
282 if (n<=0.0) {
283 n = (T)sqrt(s*s + x*x + y*y + z*z);
284 }
285}
286
287
288template <typename T> void Quaternion<T>::normalize()
289{
290 T nrm = (T)sqrt(s*s + x*x + y*y + z*z);
291
292 if (nrm>=Zero_Eps) {
293 s = s/nrm;
294 x = x/nrm;
295 y = y/nrm;
296 z = z/nrm;
297 n = (T)1.0;
298 }
299 else {
300 init();
301 }
302}
303
304
311template <typename T> void Quaternion<T>::setRotation(T e, Vector<T> v)
312{
313 if (v.n!=(T)1.0) v.normalize();
314
315 if (e>(T)PI) e = e - (T)PI2;
316 else if (e<-(T)PI) e = (T)PI2 + e;
317
318 T s2 = e/(T)2.0;
319 T sn =(T) sin(s2);
320 s = (T)cos(s2);
321 x = v.x*sn;
322 y = v.y*sn;
323 z = v.z*sn;
324 n = (T)v.n;
325 c = (T)1.0;
326}
327
328
339template <typename T> void Quaternion<T>::setExtEulerYZX(Vector<T> e)
340{
341 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
342 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
343 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
344
345 Quaternion<T> qx, qy, qz;
346 qy.setRotation(e.element1(), ey);
347 qz.setRotation(e.element2(), ez);
348 qx.setRotation(e.element3(), ex);
349
350 (*this) = qx*qz*qy;
351 if (s<(T)0.0) (*this) = - (*this);
352}
353
354
356template <typename T> void Quaternion<T>::setExtEulerXYZ(Vector<T> e)
357{
358 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
359 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
360 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
361
362 Quaternion<T> qx, qy, qz;
363 qx.setRotation(e.element1(), ex);
364 qy.setRotation(e.element2(), ey);
365 qz.setRotation(e.element3(), ez);
366
367 (*this) = qz*qy*qx;
368 if (s<(T)0.0) (*this) = - (*this);
369}
370
371
373template <typename T> void Quaternion<T>::setExtEulerZYX(Vector<T> e)
374{
375 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
376 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
377 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
378
379 Quaternion<T> qx, qy, qz;
380 qz.setRotation(e.element1(), ez);
381 qy.setRotation(e.element2(), ey);
382 qx.setRotation(e.element3(), ex);
383
384 (*this) = qx*qy*qz;
385 if (s<(T)0.0) (*this) = - (*this);
386}
387
388
390template <typename T> void Quaternion<T>::setExtEulerXZY(Vector<T> e)
391{
392 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
393 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
394 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
395
396 Quaternion<T> qx, qy, qz;
397 qx.setRotation(e.element1(), ex);
398 qz.setRotation(e.element2(), ez);
399 qy.setRotation(e.element3(), ey);
400
401 (*this) = qy*qz*qx;
402 if (s<(T)0.0) (*this) = - (*this);
403}
404
405
407template <typename T> void Quaternion<T>::setExtEulerYXZ(Vector<T> e)
408{
409 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
410 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
411 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
412
413 Quaternion<T> qx, qy, qz;
414 qy.setRotation(e.element1(), ey);
415 qx.setRotation(e.element2(), ex);
416 qz.setRotation(e.element3(), ez);
417
418 (*this) = qz*qx*qy;
419 if (s<(T)0.0) (*this) = - (*this);
420}
421
422
424template <typename T> void Quaternion<T>::setExtEulerZXY(Vector<T> e)
425{
426 Vector<T> ex((T)1.0, (T)0.0, (T)0.0, (T)1.0);
427 Vector<T> ey((T)0.0, (T)1.0, (T)0.0, (T)1.0);
428 Vector<T> ez((T)0.0, (T)0.0, (T)1.0, (T)1.0);
429
430 Quaternion<T> qx, qy, qz;
431 qz.setRotation(e.element1(), ez);
432 qx.setRotation(e.element2(), ex);
433 qy.setRotation(e.element3(), ey);
434
435 (*this) = qy*qx*qz;
436 if (s<(T)0.0) (*this) = - (*this);
437}
438
439
446{
447 Matrix<T> mtx(2, 3, 3); // 2次元マトリックス, 3x3
448
449 if (n!=(T)1.0) normalize();
450
451 mtx.element(1, 1) = (T)1.0 - (T)2.0*y*y - (T)2.0*z*z;
452 mtx.element(1, 2) = (T)2.0*x*y - (T)2.0*s*z;
453 mtx.element(1, 3) = (T)2.0*x*z + (T)2.0*s*y;
454 mtx.element(2, 1) = (T)2.0*x*y + (T)2.0*s*z;
455 mtx.element(2, 2) = (T)1.0 - (T)2.0*x*x - (T)2.0*z*z;
456 mtx.element(2, 3) = (T)2.0*y*z - (T)2.0*s*x;
457 mtx.element(3, 1) = (T)2.0*x*z - (T)2.0*s*y;
458 mtx.element(3, 2) = (T)2.0*y*z + (T)2.0*s*x;
459 mtx.element(3, 3) = (T)1.0 - (T)2.0*x*x - (T)2.0*y*y;
460
461 return mtx;
462}
463
464
467{
468 if (c<(T)0.0) return v;
469
470 Quaternion<T> inv = ~(*this);
471 Quaternion<T> qut = (*this)*(v*inv);
472 Vector<T> vct = qut.getVector();
473 vct.d = v.d;
474
475 return vct;
476}
477
478
481{
482 if (c<(T)0.0) return v;
483
484 Quaternion<T> inv = ~(*this);
485 Quaternion<T> qut = inv*(v*(*this));
486 Vector<T> vct = qut.getVector();
487 vct.d = v.d;
488
489 return vct;
490}
491
492
493
495// 回転行列,オイラー角
496//
497// オイラー角の角度は全て右手系の正の方向が基準
498// オイラー角ベクトルの成分は演算順
499// 固定座標(ベクトルの計算)
500//
501
502// ExtEuler -> Rotation Matrix
503//
504template <typename T> Matrix<T> ExtEulerXYZ2RotMatrix(Vector<T> eul)
505{
506 Matrix<T> mtx(2, 3, 3);
507
508 T sinx = (T)sin(eul.element1());
509 T cosx = (T)cos(eul.element1());
510 T siny = (T)sin(eul.element2());
511 T cosy = (T)cos(eul.element2());
512 T sinz = (T)sin(eul.element3());
513 T cosz = (T)cos(eul.element3());
514
515 mtx.element(1, 1) = cosy*cosz;
516 mtx.element(1, 2) = sinx*siny*cosz - cosx*sinz;
517 mtx.element(1, 3) = cosx*siny*cosz + sinx*sinz;
518 mtx.element(2, 1) = cosy*sinz;
519 mtx.element(2, 2) = sinx*siny*sinz + cosx*cosz;
520 mtx.element(2, 3) = cosx*siny*sinz - sinx*cosz;
521 mtx.element(3, 1) = -siny;
522 mtx.element(3, 2) = sinx*cosy;
523 mtx.element(3, 3) = cosx*cosy;
524
525 return mtx;
526}
527
528
529template <typename T> Matrix<T> ExtEulerZYX2RotMatrix(Vector<T> eul)
530{
531 Matrix<T> mtx(2, 3, 3);
532
533 T sinz = (T)sin(eul.element1());
534 T cosz = (T)cos(eul.element1());
535 T siny = (T)sin(eul.element2());
536 T cosy = (T)cos(eul.element2());
537 T sinx = (T)sin(eul.element3());
538 T cosx = (T)cos(eul.element3());
539
540 mtx.element(1, 1) = cosy*cosz;
541 mtx.element(1, 2) = -cosy*sinz;
542 mtx.element(1, 3) = siny;
543 mtx.element(2, 1) = sinx*siny*cosz + cosx*sinz;
544 mtx.element(2, 2) = -sinx*siny*sinz + cosx*cosz;
545 mtx.element(2, 3) = -sinx*cosy;
546 mtx.element(3, 1) = -cosx*siny*cosz + sinx*sinz;
547 mtx.element(3, 2) = cosx*siny*sinz + sinx*cosz;
548 mtx.element(3, 3) = cosx*cosy;
549
550 return mtx;
551}
552
553
554template <typename T> Matrix<T> ExtEulerXZY2RotMatrix(Vector<T> eul)
555{
556 Matrix<T> mtx(2, 3, 3);
557
558 T sinx = (T)sin(eul.element1());
559 T cosx = (T)cos(eul.element1());
560 T sinz = (T)sin(eul.element2());
561 T cosz = (T)cos(eul.element2());
562 T siny = (T)sin(eul.element3());
563 T cosy = (T)cos(eul.element3());
564
565 mtx.element(1, 1) = cosy*cosz;
566 mtx.element(1, 2) = -cosx*cosy*sinz + sinx*siny;
567 mtx.element(1, 3) = sinx*cosy*sinz + cosx*siny;
568 mtx.element(2, 1) = sinz;
569 mtx.element(2, 2) = cosx*cosz;
570 mtx.element(2, 3) = -sinx*cosz;
571 mtx.element(3, 1) = -siny*cosz;
572 mtx.element(3, 2) = cosx*siny*sinz + sinx*cosy;
573 mtx.element(3, 3) = -sinx*siny*sinz + cosx*cosy;
574
575 return mtx;
576}
577
578
579template <typename T> Matrix<T> ExtEulerYZX2RotMatrix(Vector<T> eul)
580{
581 Matrix<T> mtx(2, 3, 3);
582
583 T siny = (T)sin(eul.element1());
584 T cosy = (T)cos(eul.element1());
585 T sinz = (T)sin(eul.element2());
586 T cosz = (T)cos(eul.element2());
587 T sinx = (T)sin(eul.element3());
588 T cosx = (T)cos(eul.element3());
589
590 mtx.element(1, 1) = cosy*cosz;
591 mtx.element(1, 2) = -sinz;
592 mtx.element(1, 3) = siny*cosz;
593 mtx.element(2, 1) = cosx*cosy*sinz + sinx*siny;
594 mtx.element(2, 2) = cosx*cosz;
595 mtx.element(2, 3) = cosx*siny*sinz - sinx*cosy;
596 mtx.element(3, 1) = sinx*cosy*sinz - cosx*siny;
597 mtx.element(3, 2) = sinx*cosz;
598 mtx.element(3, 3) = sinx*siny*sinz + cosx*cosy;
599
600 return mtx;
601}
602
603
604template <typename T> Matrix<T> ExtEulerZXY2RotMatrix(Vector<T> eul)
605{
606 Matrix<T> mtx(2, 3, 3);
607
608 T sinz = (T)sin(eul.element1());
609 T cosz = (T)cos(eul.element1());
610 T sinx = (T)sin(eul.element2());
611 T cosx = (T)cos(eul.element2());
612 T siny = (T)sin(eul.element3());
613 T cosy = (T)cos(eul.element3());
614
615 mtx.element(1, 1) = sinx*siny*sinz + cosy*cosz;
616 mtx.element(1, 2) = sinx*siny*cosz - cosy*sinz;
617 mtx.element(1, 3) = cosx*siny;
618 mtx.element(2, 1) = cosx*sinz;
619 mtx.element(2, 2) = cosx*cosz;
620 mtx.element(2, 3) = -sinx;
621 mtx.element(3, 1) = sinx*cosy*sinz - siny*cosz;
622 mtx.element(3, 2) = sinx*cosy*cosz + siny*sinz;
623 mtx.element(3, 3) = cosx*cosy;
624
625 return mtx;
626}
627
628
629template <typename T> Matrix<T> ExtEulerYXZ2RotMatrix(Vector<T> eul)
630{
631 Matrix<T> mtx(2, 3, 3);
632
633 T siny = (T)sin(eul.element1());
634 T cosy = (T)cos(eul.element1());
635 T sinx = (T)sin(eul.element2());
636 T cosx = (T)cos(eul.element2());
637 T sinz = (T)sin(eul.element3());
638 T cosz = (T)cos(eul.element3());
639
640 mtx.element(1, 1) = -sinx*siny*sinz + cosy*cosz;
641 mtx.element(1, 2) = -cosx*sinz;
642 mtx.element(1, 3) = sinx*cosy*sinz + siny*cosz;
643 mtx.element(2, 1) = sinx*siny*cosz + cosy*sinz;
644 mtx.element(2, 2) = cosx*cosz;
645 mtx.element(2, 3) = -sinx*cosy*cosz + siny*sinz;
646 mtx.element(3, 1) = -cosx*siny;
647 mtx.element(3, 2) = sinx;
648 mtx.element(3, 3) = cosx*cosy;
649
650 return mtx;
651}
652
653
654// Rotation Matrix Elements -> ExtEuler
655//
656template <typename T> Vector<T> RotMatrixElements2ExtEulerXYZ(T m11, T m12, T m13, T m21, T m31, T m32, T m33, Vector<T>* vct=NULL)
657{
658 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
659 Vector<T> ev[2];
660 T arctang;
661
662 if (m31<-(T)1.0 || m31>(T)1.0) return eul;
663
664 if ((T)1.0-m31<(T)Zero_Eps || (T)1.0+m31<(T)Zero_Eps) {
665 if ((T)1.0-m31<Zero_Eps) { // m31==1.0
666 ev[0].y = ev[1].y = -(T)PI_DIV2;
667 ev[0].z = (T)0.0;
668 ev[1].z = (T)PI_DIV2;
669 arctang = (T)atan2(-m12, -m13);
670 ev[0].x = arctang - ev[0].z;
671 ev[1].x = arctang - ev[1].z;
672 }
673 else { // m31==-1.0
674 ev[0].y = ev[1].y = (T)PI_DIV2;
675 ev[0].z = (T)0.0;
676 ev[1].z = (T)PI_DIV2;
677 arctang = (T)atan2(m12, m13);
678 ev[0].x = arctang + ev[0].z;
679 ev[1].x = arctang + ev[1].z;
680 }
681 }
682
683 else {
684 ev[0].y = -(T)asin(m31);
685 if (ev[0].y>=(T)0.0) ev[1].y = (T)PI - ev[0].y; // 別解
686 else ev[1].y = - (T)PI - ev[0].y;
687
688 T cy1 = (T)cos(ev[0].y);
689 T cy2 = (T)cos(ev[1].y);
690 if (Xabs(cy1)<(T)Zero_Eps || Xabs(cy2)<(T)Zero_Eps) return eul;
691
692 ev[0].x = (T)atan2(m32/cy1, m33/cy1);
693 ev[0].z = (T)atan2(m21/cy1, m11/cy1);
694
695 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
696 else ev[1].x = ev[0].x + (T)PI;
697 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
698 else ev[1].z = ev[0].z + (T)PI;
699 }
700
701 //
702 // XYZ
703 if (vct!=NULL) {
704 vct[0].set(ev[0].x, ev[0].y, ev[0].z);
705 vct[1].set(ev[1].x, ev[1].y, ev[1].z);
706 }
707 eul.set(ev[0].x, ev[0].y, ev[0].z);
708
709 return eul;
710}
711
712
713template <typename T> Vector<T> RotMatrixElements2ExtEulerZYX(T m11, T m12, T m13, T m21, T m23, T m31, T m33, Vector<T>* vct=NULL)
714{
715 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
716 Vector<T> ev[2];
717 T arctang;
718
719 if (m13<-(T)1.0 || m13>(T)1.0) return eul;
720
721 if ((T)1.0-m13<(T)Zero_Eps || (T)1.0+m13<(T)Zero_Eps) {
722 if ((T)1.0-m13<(T)Zero_Eps) { // m13==1.0
723 ev[0].y = ev[1].y = (T)PI_DIV2;
724 ev[0].z = (T)0.0;
725 ev[1].z = (T)PI_DIV2;
726 arctang = (T)atan2(m21, -m31);
727 ev[0].x = (T)arctang - ev[0].z;
728 ev[1].x = (T)arctang - ev[1].z;
729 }
730 else { // m13==-1.0
731 ev[0].y = ev[1].y = -(T)PI_DIV2;
732 ev[0].z = (T)0.0;
733 ev[1].z = (T)PI_DIV2;
734 arctang = (T)atan2(-m21, m31);
735 ev[0].x = (T)arctang + ev[0].z;
736 ev[1].x = (T)arctang + ev[1].z;
737 }
738 }
739
740 else {
741 ev[0].y = (T)asin(m13);
742 if (ev[0].y>=0.0) ev[1].y = (T)PI - ev[0].y;
743 else ev[1].y = -(T)PI - ev[0].y;
744
745 T cy1 = (T)cos(ev[0].y);
746 T cy2 = (T)cos(ev[1].y);
747 if (Xabs(cy1)<Zero_Eps || Xabs(cy2)<Zero_Eps) return eul;
748
749 ev[0].x = atan2(-m23/cy1, m33/cy1);
750 ev[0].z = atan2(-m12/cy1, m11/cy1);
751
752 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
753 else ev[1].x = ev[0].x + (T)PI;
754 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
755 else ev[1].z = ev[0].z + (T)PI;
756 }
757
758 //
759 // ZYX
760 if (vct!=NULL) {
761 vct[0].set(ev[0].z, ev[0].y, ev[0].x);
762 vct[1].set(ev[1].z, ev[1].y, ev[1].x);
763 }
764 eul.set(ev[0].z, ev[0].y, ev[0].x);
765
766 return eul;
767}
768
769
770template <typename T> Vector<T> RotMatrixElements2ExtEulerXZY(T m11, T m12, T m13, T m21, T m22, T m23, T m31, Vector<T>* vct=NULL)
771{
772 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
773 Vector<T> ev[2];
774 T arctang;
775
776 if (m21<-(T)1.0 || m21>(T)1.0) return eul;
777
778 if ((T)1.0-m21<(T)Zero_Eps || (T)1.0+m21<(T)Zero_Eps) {
779 if ((T)1.0-m21<(T)Zero_Eps) { // m21==1.0
780 ev[0].z = ev[1].z = (T)PI_DIV2;
781 ev[0].y = (T)0.0;
782 ev[1].y = (T)PI_DIV2;
783 arctang = (T)atan2(m13, -m12);
784 ev[0].x = arctang - ev[0].y;
785 ev[1].x = arctang - ev[1].y;
786 }
787 else { // m21==-1.0
788 ev[0].z = ev[1].y = -(T)PI_DIV2;
789 ev[0].y = (T)0.0;
790 ev[1].y = (T)PI_DIV2;
791 arctang = (T)atan2(-m13, m12);
792 ev[0].x = arctang + ev[0].y;
793 ev[1].x = arctang + ev[1].y;
794 }
795 }
796
797 else {
798 ev[0].z = (T)asin(m21);
799 if (ev[0].z>=(T)0.0) ev[1].z = (T)PI - ev[0].z;
800 else ev[1].z = -(T)PI - ev[0].z;
801
802 T cz1 = (T)cos(ev[0].z);
803 T cz2 = (T)cos(ev[1].z);
804 if (Xabs(cz1)<(T)Zero_Eps || Xabs(cz2)<(T)Zero_Eps) return eul;
805
806 ev[0].x = (T)atan2(-m23/cz1, m22/cz1);
807 ev[0].y = (T)atan2(-m31/cz1, m11/cz1);
808
809 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
810 else ev[1].x = ev[0].x + (T)PI;
811 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
812 else ev[1].y = ev[0].y + (T)PI;
813 }
814
815 //
816 // XZY
817 if (vct!=NULL) {
818 vct[0].set(ev[0].x, ev[0].z, ev[0].y);
819 vct[1].set(ev[1].x, ev[1].z, ev[1].y);
820 }
821 eul.set(ev[0].x, ev[0].z, ev[0].y);
822
823 return eul;
824}
825
826
827template <typename T> Vector<T> RotMatrixElements2ExtEulerYZX(T m11, T m12, T m13, T m21, T m22, T m31, T m32, Vector<T>* vct=NULL)
828{
829 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
830 Vector<T> ev[2];
831 T arctang;
832
833 if (m12<-(T)1.0 || m12>(T)1.0) return eul;
834
835 if ((T)1.0-m12<(T)Zero_Eps || (T)1.0+m12<(T)Zero_Eps) {
836 if (1.0-m12<Zero_Eps) { // m12==1.0
837 ev[0].z = ev[1].z = -(T)PI_DIV2;
838 ev[0].y = (T)0.0;
839 ev[1].y = (T)PI_DIV2;
840 arctang = (T)atan2(-m31, -m21);
841 ev[0].x = arctang - ev[0].y;
842 ev[1].x = arctang - ev[1].y;
843 }
844 else { // m12==-1.0
845 ev[0].z = ev[1].y = (T)PI_DIV2;
846 ev[0].y = (T)0.0;
847 ev[1].y = (T)PI_DIV2;
848 arctang = (T)atan2(m31, m21);
849 ev[0].x = arctang + ev[0].y;
850 ev[1].x = arctang + ev[1].y;
851 }
852 }
853
854 else {
855 ev[0].z = -(T)asin(m12);
856 if (ev[0].z>=0.0) ev[1].z = (T)PI - ev[0].z;
857 else ev[1].z = -(T)PI - ev[0].z;
858
859 T cz1 = (T)cos(ev[0].z);
860 T cz2 = (T)cos(ev[1].z);
861 if (Xabs(cz1)<(T)Zero_Eps || Xabs(cz2)<(T)Zero_Eps) return eul;
862
863 ev[0].x = (T)atan2(m32/cz1, m22/cz1);
864 ev[0].y = (T)atan2(m13/cz1, m11/cz1);
865
866 if (ev[0].x>=(T)0.0) ev[1].x = ev[0].x - (T)PI;
867 else ev[1].x = ev[0].x + (T)PI;
868 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
869 else ev[1].y = ev[0].y + (T)PI;
870 }
871
872 //
873 // YZX
874 if (vct!=NULL) {
875 vct[0].set(ev[0].y, ev[0].z, ev[0].x);
876 vct[1].set(ev[1].y, ev[1].z, ev[1].x);
877 }
878 eul.set(ev[0].y, ev[0].z, ev[0].x);
879
880 return eul;
881}
882
883
884template <typename T> Vector<T> RotMatrixElements2ExtEulerYXZ(T m12, T m21, T m22, T m23, T m31, T m32, T m33, Vector<T>* vct=NULL)
885{
886 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
887 Vector<T> ev[2];
888 T arctang;
889
890 if (m32<-(T)1.0 || m32>(T)1.0) return eul;
891
892 if ((T)1.0-m32<(T)Zero_Eps || (T)1.0+m32<(T)Zero_Eps) {
893 if ((T)1.0-m32<(T)Zero_Eps) { // m32==1.0
894 ev[0].x = ev[1].x = (T)PI_DIV2;
895 ev[0].z = (T)0.0;
896 ev[1].z = (T)PI_DIV2;
897 arctang = (T)atan2(m21, -m23);
898 ev[0].y = arctang - ev[0].z;
899 ev[1].y = arctang - ev[1].z;
900 }
901 else { // m32==-1.0
902 ev[0].x = ev[1].x = -(T)PI_DIV2;
903 ev[0].z = (T)0.0;
904 ev[1].z = (T)PI_DIV2;
905 arctang = (T)atan2(-m21, m23);
906 ev[0].y = arctang + ev[0].z;
907 ev[1].y = arctang + ev[1].z;
908 }
909 }
910
911 else {
912 ev[0].x = (T)asin(m32);
913 if (ev[0].x>=0.0) ev[1].x = (T)PI - ev[0].x;
914 else ev[1].x = -(T)PI - ev[0].x;
915
916 T cx1 = (T)cos(ev[0].x);
917 T cx2 = (T)cos(ev[1].x);
918 if (Xabs(cx1)<(T)Zero_Eps || Xabs(cx2)<(T)Zero_Eps) return eul;
919
920 ev[0].y = (T)atan2(-m31/cx1, m33/cx1);
921 ev[0].z = (T)atan2(-m12/cx1, m22/cx1);
922
923 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
924 else ev[1].y = ev[0].y + (T)PI;
925 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
926 else ev[1].z = ev[0].z + (T)PI;
927 }
928
929 //
930 // YXZ
931 if (vct!=NULL) {
932 vct[0].set(ev[0].y, ev[0].x, ev[0].z);
933 vct[1].set(ev[1].y, ev[1].x, ev[1].z);
934 }
935 eul.set(ev[0].y, ev[0].x, ev[0].z);
936
937 return eul;
938}
939
940
941template <typename T> Vector<T> RotMatrixElements2ExtEulerZXY(T m12, T m13, T m21, T m22, T m23, T m32, T m33, Vector<T>* vct=NULL)
942{
943 Vector<T> eul((T)0.0, (T)0.0, (T)0.0, (T)0.0, -(T)1.0);
944 Vector<T> ev[2];
945 T arctang;
946
947 if (m23<-(T)1.0 || m23>(T)1.0) return eul;
948
949 if ((T)1.0-m23<(T)Zero_Eps || (T)1.0+m23<(T)Zero_Eps) {
950 if ((T)1.0-m23<(T)Zero_Eps) { // m23==1.0
951 ev[0].x = ev[1].x = -(T)PI_DIV2;
952 ev[0].z = (T)0.0;
953 ev[1].z = (T)PI_DIV2;
954 arctang = (T)atan2(-m12, -m32);
955 ev[0].y = arctang - ev[0].z;
956 ev[1].y = arctang - ev[1].z;
957 }
958 else { // m23==-1.0
959 ev[0].x = ev[1].x = (T)PI_DIV2;
960 ev[0].z = (T)0.0;
961 ev[1].z = (T)PI_DIV2;
962 arctang = (T)atan2(m12, m32);
963 ev[0].y = arctang + ev[0].z;
964 ev[1].y = arctang + ev[1].z;
965 }
966 }
967
968 else {
969 ev[0].x = -(T)asin(m23);
970 if (ev[0].x>=(T)0.0) ev[1].x = (T)PI - ev[0].x;
971 else ev[1].x = -(T)PI - ev[0].x;
972
973 T cx1 = (T)cos(ev[0].x);
974 T cx2 = (T)cos(ev[1].x);
975 if (Xabs(cx1)<(T)Zero_Eps || Xabs(cx2)<(T)Zero_Eps) return eul;
976
977 ev[0].y = (T)atan2(m13/cx1, m33/cx1);
978 ev[0].z = (T)atan2(m21/cx1, m22/cx1);
979
980 if (ev[0].y>=(T)0.0) ev[1].y = ev[0].y - (T)PI;
981 else ev[1].y = ev[0].y + (T)PI;
982 if (ev[0].z>=(T)0.0) ev[1].z = ev[0].z - (T)PI;
983 else ev[1].z = ev[0].z + (T)PI;
984 }
985
986 //
987 // ZXY
988 if (vct!=NULL) {
989 vct[0].set(ev[0].z, ev[0].x, ev[0].y);
990 vct[1].set(ev[1].z, ev[1].x, ev[1].y);
991 }
992 eul.set(ev[0].z, ev[0].x, ev[0].y);
993
994 return eul;
995}
996
997
998// Rotation Matrix -> ExtEuler
999//
1000template <typename T> Vector<T> RotMatrix2ExtEulerXYZ(Matrix<T> mtx, Vector<T>* vct=NULL)
1001{
1002 T m11 = mtx.element(1, 1);
1003 T m12 = mtx.element(1, 2);
1004 T m13 = mtx.element(1, 3);
1005 T m21 = mtx.element(2, 1);
1006 T m31 = mtx.element(3, 1);
1007 T m32 = mtx.element(3, 2);
1008 T m33 = mtx.element(3, 3);
1009
1010 Vector<T> eul = RotMatrixElements2ExtEulerXYZ<T>(m11, m12, m13, m21, m31, m32, m33, vct);
1011
1012 return eul;
1013}
1014
1015
1016//template <typename T> Vector<T> RotMatrix2ExtEulerZYX(Matrix<T> mtx, Vector<T>* vct=NULL)
1017template <typename T> Vector<T> RotMatrix2ExtEulerZYX(Matrix<T> mtx, Vector<T>* vct)
1018{
1019 T m11 = mtx.element(1, 1);
1020 T m12 = mtx.element(1, 2);
1021 T m13 = mtx.element(1, 3);
1022 T m21 = mtx.element(2, 1);
1023 T m23 = mtx.element(2, 3);
1024 T m31 = mtx.element(3, 1);
1025 T m33 = mtx.element(3, 3);
1026
1027 Vector<T> eul = RotMatrixElements2ExtEulerZYX<T>(m11, m12, m13, m21, m23, m31, m33, vct);
1028
1029 return eul;
1030}
1031
1032
1033template <typename T> Vector<T> RotMatrix2ExtEulerXZY(Matrix<T> mtx, Vector<T>* vct=NULL)
1034{
1035 T m11 = mtx.element(1, 1);
1036 T m12 = mtx.element(1, 2);
1037 T m13 = mtx.element(1, 3);
1038 T m21 = mtx.element(2, 1);
1039 T m22 = mtx.element(2, 2);
1040 T m23 = mtx.element(2, 3);
1041 T m31 = mtx.element(3, 1);
1042
1043 Vector<T> eul = RotMatrixElements2ExtEulerXZY<T>(m11, m12, m13, m21, m22, m23, m31, vct);
1044
1045 return eul;
1046}
1047
1048
1049template <typename T> Vector<T> RotMatrix2ExtEulerYZX(Matrix<T> mtx, Vector<T>* vct=NULL)
1050{
1051 T m11 = mtx.element(1, 1);
1052 T m12 = mtx.element(1, 2);
1053 T m13 = mtx.element(1, 3);
1054 T m21 = mtx.element(2, 1);
1055 T m22 = mtx.element(2, 2);
1056 T m31 = mtx.element(3, 1);
1057 T m32 = mtx.element(3, 2);
1058
1059 Vector<T> eul = RotMatrixElements2ExtEulerYZX<T>(m11, m12, m13, m21, m22, m31, m32, vct);
1060
1061 return eul;
1062}
1063
1064
1065template <typename T> Vector<T> RotMatrix2ExtEulerYXZ(Matrix<T> mtx, Vector<T>* vct=NULL)
1066{
1067 T m12 = mtx.element(1, 2);
1068 T m21 = mtx.element(2, 1);
1069 T m22 = mtx.element(2, 2);
1070 T m23 = mtx.element(2, 3);
1071 T m31 = mtx.element(3, 1);
1072 T m32 = mtx.element(3, 2);
1073 T m33 = mtx.element(3, 3);
1074
1075 Vector<T> eul = RotMatrixElements2ExtEulerYXZ<T>(m12, m21, m22, m23, m31, m32, m33, vct);
1076
1077 return eul;
1078}
1079
1080
1081template <typename T> Vector<T> RotMatrix2ExtEulerZXY(Matrix<T> mtx, Vector<T>* vct=NULL)
1082{
1083 T m12 = mtx.element(1, 2);
1084 T m13 = mtx.element(1, 3);
1085 T m21 = mtx.element(2, 1);
1086 T m22 = mtx.element(2, 2);
1087 T m23 = mtx.element(2, 3);
1088 T m32 = mtx.element(3, 2);
1089 T m33 = mtx.element(3, 3);
1090
1091 Vector<T> eul = RotMatrixElements2ExtEulerZXY<T>(m12, m13, m21, m22, m23, m32, m33, vct);
1092
1093 return eul;
1094}
1095
1096
1097// Quaternion -> ExtEuler
1098//
1099//template <typename T> Vector<T> Quaternion2ExtEulerXYZ(Quaternion<T> qut, Vector<T>* vct=NULL)
1101{
1102 Matrix<T> mtx = qut.getRotMatrix();
1103 Vector<T> eul = RotMatrix2ExtEulerXYZ<T>(mtx, vct);
1104 mtx.free();
1105
1106 return eul;
1107}
1108
1109
1110//template <typename T> Vector<T> Quaternion2ExtEulerZYX(Quaternion<T> qut, Vector<T>* vct=NULL)
1112{
1113 Matrix<T> mtx = qut.getRotMatrix();
1114 Vector<T> eul = RotMatrix2ExtEulerZYX(mtx, vct);
1115 mtx.free();
1116
1117 return eul;
1118}
1119
1120
1121//template <typename T> Vector<T> Quaternion2ExtEulerXZY(Quaternion<T> qut, Vector<T>* vct=NULL)
1123{
1124 Matrix<T> mtx = qut.getRotMatrix();
1125 Vector<T> eul = RotMatrix2ExtEulerXZY(mtx, vct);
1126 mtx.free();
1127
1128 return eul;
1129}
1130
1131
1132//template <typename T> Vector<T> Quaternion2ExtEulerYZX(Quaternion<T> qut, Vector<T>* vct=NULL)
1134{
1135 Matrix<T> mtx = qut.getRotMatrix();
1136 Vector<T> eul = RotMatrix2ExtEulerYZX(mtx, vct);
1137 mtx.free();
1138
1139 return eul;
1140}
1141
1142
1143//template <typename T> Vector<T> Quaternion2ExtEulerYXZ(Quaternion<T> qut, Vector<T>* vct=NULL)
1145{
1146 Matrix<T> mtx = qut.getRotMatrix();
1147 Vector<T> eul = RotMatrix2ExtEulerYXZ(mtx, vct);
1148 mtx.free();
1149
1150 return eul;
1151}
1152
1153
1154//template <typename T> Vector<T> Quaternion2ExtEulerZXY(Quaternion<T> qut, Vector<T>* vct=NULL)
1156{
1157 Matrix<T> mtx = qut.getRotMatrix();
1158 Vector<T> eul = RotMatrix2ExtEulerZXY(mtx, vct);
1159 mtx.free();
1160
1161 return eul;
1162}
1163
1164
1165// Rotation Matrix -> Quaternion
1166//
1168{
1169 Quaternion<T> qut;
1171 qut.setExtEulerXYZ(xyz);
1172
1173 return qut;
1174}
1175
1176
1177
1179// ベクトルの回転,クォータニオン
1180//
1181
1188{
1189 Vector<T> vect;
1190
1191 vect.x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v.x +
1192 ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v.y +
1193 ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v.z;
1194
1195 vect.y = ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v.x +
1196 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v.y +
1197 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v.z;
1198
1199 vect.z = ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v.x +
1200 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v.y +
1201 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v.z;
1202
1203 return vect;
1204}
1205
1206
1208{
1209 Vector<T> vect;
1210
1211 vect.x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v.x +
1212 ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v.y +
1213 ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v.z;
1214
1215 vect.y = ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v.x +
1216 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v.y +
1217 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v.z;
1218
1219 vect.z = ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v.x +
1220 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v.y +
1221 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v.z;
1222
1223 return vect;
1224}
1225
1226
1227template <typename T> T* VectorRotation(T* v, Quaternion<T> q)
1228{
1229 T x, y, z;
1230
1231 x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v[0] +
1232 ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v[1] +
1233 ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v[2];
1234
1235 y = ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v[0] +
1236 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v[1] +
1237 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v[2];
1238
1239 z = ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v[0] +
1240 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v[1] +
1241 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v[2];
1242
1243 v[0] = x;
1244 v[1] = y;
1245 v[2] = z;
1246
1247 return v;
1248}
1249
1250
1251template <typename T> T* VectorInvRotation(T* v, Quaternion<T> q)
1252{
1253 T x, y, z;
1254
1255 x = (q.s*q.s + q.x*q.x - q.y*q.y -q.z*q.z)*v[0] +
1256 ((T)2.0*q.x*q.y + (T)2.0*q.s*q.z)*v[1] +
1257 ((T)2.0*q.x*q.z - (T)2.0*q.s*q.y)*v[2];
1258
1259 y = ((T)2.0*q.x*q.y - (T)2.0*q.s*q.z)*v[0] +
1260 (q.s*q.s - q.x*q.x + q.y*q.y - q.z*q.z)*v[1] +
1261 ((T)2.0*q.y*q.z + (T)2.0*q.s*q.x)*v[2];
1262
1263 z = ((T)2.0*q.x*q.z + (T)2.0*q.s*q.y)*v[0] +
1264 ((T)2.0*q.y*q.z - (T)2.0*q.s*q.x)*v[1] +
1265 (q.s*q.s - q.x*q.x - q.y*q.y + q.z*q.z)*v[2];
1266
1267 v[0] = x;
1268 v[1] = y;
1269 v[2] = z;
1270
1271 return v;
1272}
1273
1274
1276{
1277 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
1278
1279 a.normalize();
1280 b.normalize();
1281 if (a.n<(T)Zero_Eps || b.n<(T)Zero_Eps) return qut;
1282
1283 Vector<T> nr = a^b;
1284 nr.normalize();
1285
1286 T cs2 = (a*b)/(T)2.0; // θ/2 = 0〜π/2
1287
1288 T sn;
1289 if (cs2>(T)0.5) sn = (T)0.0;
1290 else sn = (T)sqrt(0.5 - cs2);
1291
1292 if (Xabs(sn-(T)1.0)<(T)Zero_Eps) {
1293 Vector<T> c = a + b;
1294 if (c.norm()<(T)1.0) {
1295 qut.setRotation(PI, nr);
1296 if (nr.n<Zero_Eps) {
1297 qut.s = (T)0.0;
1298 qut.n = (T)0.0;
1299 qut.c = -(T)1.0;
1300 }
1301 }
1302 else {
1303 qut.setRotation((T)0.0, nr);
1304 }
1305 return qut;
1306 }
1307
1308 T cs;
1309 if (cs2<-(T)0.5) cs = (T)0.0;
1310 else cs = (T)sqrt(0.5 + cs2);
1311
1312 //
1313 if (cs>(T)1.0) qut.set((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0, -(T)1.0);
1314 else qut.set(cs, nr.x*sn, nr.y*sn, nr.z*sn, (T)1.0, (T)Min(a.c, b.c));
1315
1316 return qut;
1317}
1318
1319
1321{
1322 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
1323
1324 if (a.c<(T)0.0 || b.c<(T)0.0 || c.c<(T)0.0) return qut;
1325
1326 qut = V2VQuaternion<T>(b-a, c-b);
1327 return qut;
1328}
1329
1330
1332{
1333 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
1334
1335 if (a.c<(T)0.0 || b.c<(T)0.0 || c.c<(T)0.0) return qut;
1336
1337 qut = V2VQuaternion<T>(a, c-b);
1338 return qut;
1339}
1340
1341
1343{
1344 Quaternion<T> qut((T)1.0, (T)0.0, (T)0.0, (T)0.0, (T)1.0);
1345
1346 if (a.c<(T)0.0 || b.c<(T)0.0 || c.c<(T)0.0) return qut;
1347
1348 qut = V2VQuaternion<T>(b-a, c);
1349 return qut;
1350}
1351
1352
1370{
1371 if (qa.n!=(T)1.0) qa.normalize();
1372 if (qb.n!=(T)1.0) qb.normalize();
1373
1374 //
1375 T dot;
1376 Quaternion<T> qc;
1377
1379 //
1380 Vector<T> va = qa.getVector();
1381 Vector<T> vb = qb.getVector();
1382 va.normalize();
1383 vb.normalize();
1384
1385 //
1386 dot = va*vb;
1387 if (dot>(T)1.0) dot = 1.0;
1388 else if (dot<-(T)1.0) dot = -1.0;
1389
1390 // 回転軸が変わらない場合
1391 if (dot>(T)1.0-Sin_Tolerance) {
1392 T anga = qa.getMathAngle();
1393 T angb = qb.getMathAngle();
1394 T angd = angb - anga;
1395 if (angd<-(T)PI) angd += (T)PI2;
1396 else if (angd>(T)PI) angd -= (T)PI2;
1397
1398 T angc = anga + t*angd;
1399 qc.setRotation(angc, va);
1400 qc.normalize();
1401 return qc;
1402 }
1403
1404 // 回転軸が反転する場合
1405// else if (dot<-(T)1.0+(T)Sin_Tolerance) {
1406 else if (dot<-(T)0.99) {
1407 T anga = qa.getMathAngle();
1408 T angb = - qb.getMathAngle();
1409 T angd = angb - anga;
1410 if (angd<-(T)PI) angd += (T)PI2;
1411 else if (angd>(T)PI) angd -= (T)PI2;
1412
1413 T angc = anga + t*angd;
1414 qc.setRotation(angc, va);
1415 qc.normalize();
1416 return qc;
1417 }
1418
1419 // SLERP
1420 dot = qa.x*qb.x + qa.y*qb.y + qa.z*qb.z + qa.s*qb.s;
1421 if (dot>(T)1.0) dot = (T)1.0;
1422 else if (dot<(T)0.0) {
1423 if (t<=(T)0.5) return qa;
1424 else return qb;
1425 }
1426 //if (dot<0.0) DEBUG_WARN("WARNING: SlerpQuaternion: dot = %f", dot);
1427
1428 //
1429 T th = (T)acos(dot);
1430 T sn = (T)sin(th);
1431 if (Xabs(sn)<(T)Sin_Tolerance) return qa;
1432
1433 //
1434 qc = qa*((T)sin(((T)1.0-t)*th)/sn) + qb*((T)sin(t*th)/sn);
1435 qc.normalize();
1436
1437 return qc;
1438}
1439
1440
1441} // namespace
1442
1443
1444#endif
1445
マトリックス ライブラリヘッダ for C++
ベクトルライブラリ for C++
T & element(int i,...)
Definition Matrix++.h:204
void free()
free() は手動で呼び出す.
Definition Matrix++.h:52
Quaternion(T S, Vector< T > v)
Definition Rotation.h:57
T getMathAngle()
-π〜π
Definition Rotation.h:69
T c
信頼度
Definition Rotation.h:52
T y
y 成分
Definition Rotation.h:48
void setExtEulerXZY(Vector< T > e)
X->Z->Y.
Definition Rotation.h:390
Vector< T > getExtEulerXYZ(Vector< T > *vt=NULL)
Definition Rotation.h:87
void set(T S, T X, T Y, T Z, T N=(T) 0.0, T C=(T) 1.0)
Definition Rotation.h:273
Vector< T > getExtEulerYZX(Vector< T > *vt=NULL)
Definition Rotation.h:90
Vector< T > getExtEulerXZY(Vector< T > *vt=NULL)
Definition Rotation.h:89
void init(T C=(T) 1.0)
Definition Rotation.h:64
void setRotation(T e, Vector< T > v)
Definition Rotation.h:311
void normalize(void)
Definition Rotation.h:288
void setRotate(T e, Vector< T > v)
Definition Rotation.h:76
void setRotate(T e, T X, T Y, T Z, T N=(T) 0.0)
Definition Rotation.h:77
virtual ~Quaternion(void)
Definition Rotation.h:58
Matrix< T > getRotMatrix()
Definition Rotation.h:445
T getAngle()
0〜2π
Definition Rotation.h:68
T x
x 成分
Definition Rotation.h:47
void setExtEulerZYX(Vector< T > e)
Z->Y->X.
Definition Rotation.h:373
T z
z 成分
Definition Rotation.h:49
void setExtEulerXYZ(Vector< T > e)
X->Y->Z.
Definition Rotation.h:356
Vector< T > getExtEulerYXZ(Vector< T > *vt=NULL)
Definition Rotation.h:91
void setExtEulerYXZ(Vector< T > e)
Y->X->Z.
Definition Rotation.h:407
Vector< T > getExtEulerZYX(Vector< T > *vt=NULL)
Definition Rotation.h:88
Vector< T > execInvRotate(Vector< T > v)
Definition Rotation.h:97
Vector< T > execRotate(Vector< T > v)
Definition Rotation.h:96
Vector< T > execInvRotation(Vector< T > v)
Exec Inv Rotation (~q)vq.
Definition Rotation.h:480
T n
ノルム
Definition Rotation.h:51
T s
cos(θ/2)
Definition Rotation.h:46
void setExtEulerZXY(Vector< T > e)
Z->X->Y.
Definition Rotation.h:424
Vector< T > execRotation(Vector< T > v)
Exec Rotation qv(~q)
Definition Rotation.h:466
Quaternion(T S, T X, T Y, T Z, T N=(T) 0.0, T C=(T) 1.0)
Definition Rotation.h:56
Vector< T > getExtEulerZXY(Vector< T > *vt=NULL)
Definition Rotation.h:92
void setRotation(T e, T X, T Y, T Z, T N=(T) 0.0)
Definition Rotation.h:74
void setExtEulerYZX(Vector< T > e)
Y->Z->X.
Definition Rotation.h:339
Vector< T > getVector()
Definition Rotation.h:66
T & element2(void)
Definition Vector.h:79
T & element1(void)
Definition Vector.h:78
double c
信頼度
Definition Vector.h:63
Vector< T > normalize(void)
Definition Vector.h:87
int d
汎用
Definition Vector.h:64
double norm(void)
Definition Vector.h:71
void set(T X, T Y=0, T Z=0, double N=0.0, double C=1.0, int D=0)
Definition Vector.h:110
double n
ノルム
Definition Vector.h:62
T & element3(void)
Definition Vector.h:80
#define Min(x, y)
Definition common.h:250
#define PI2
Definition common.h:184
#define PI
Definition common.h:182
#define Xabs(x)
Definition common.h:257
#define PI_DIV2
Definition common.h:185
#define DllExport
Definition common.h:105
Definition Brep.h:29
Matrix< T > ExtEulerYXZ2RotMatrix(Vector< T > eul)
Definition Rotation.h:629
Quaternion< T > PPVQuaternion(Vector< T > a, Vector< T > b, Vector< T > c)
Definition Rotation.h:1342
Quaternion< T > ExtEulerXYZ2Quaternion(Vector< T > e)
Definition Rotation.h:236
Vector< T > Quaternion2ExtEulerXYZ(Quaternion< T > qut, Vector< T > *vct=NULL)
Definition Rotation.h:1100
Vector< T > RotMatrix2ExtEulerZXY(Matrix< T > mtx, Vector< T > *vct=NULL)
Definition Rotation.h:1081
Vector< T > RotMatrix2ExtEulerYXZ(Matrix< T > mtx, Vector< T > *vct=NULL)
Definition Rotation.h:1065
Quaternion< T > ExtEulerYXZ2Quaternion(Vector< T > e)
Definition Rotation.h:240
Quaternion< T > operator~(const Quaternion< T > a)
Definition Rotation.h:114
AffineTrans< T > operator*(AffineTrans< T > a, AffineTrans< T > b)
Matrix< T > operator+(const Matrix< T > a, const Matrix< T > b)
Definition Matrix++.h:386
Matrix< T > ExtEulerZXY2RotMatrix(Vector< T > eul)
Definition Rotation.h:604
Vector< T > RotMatrixElements2ExtEulerYXZ(T m12, T m21, T m22, T m23, T m31, T m32, T m33, Vector< T > *vct=NULL)
Definition Rotation.h:884
double Zero_Eps
1に対して 0とするトレランス
Definition Tolerance.cpp:26
Quaternion< T > ExtEulerZXY2Quaternion(Vector< T > e)
Definition Rotation.h:241
Matrix< T > ExtEulerXZY2RotMatrix(Vector< T > eul)
Definition Rotation.h:554
Vector< T > VectorRotation(Vector< T > v, Quaternion< T > q)
Definition Rotation.h:1187
Matrix< T > operator/(const Matrix< T > a, const R d)
Definition Matrix++.h:427
bool operator==(const Matrix< T > v1, const Matrix< T > v2)
Definition Matrix++.h:435
Vector< T > Quaternion2ExtEulerZXY(Quaternion< T > qut, Vector< T > *vct=NULL)
Definition Rotation.h:1155
Vector< T > RotMatrix2ExtEulerXYZ(Matrix< T > mtx, Vector< T > *vct=NULL)
Definition Rotation.h:1000
bool operator!=(const Quaternion< T > q1, const Quaternion< T > q2)
~ 共役
Definition Rotation.h:109
Vector< T > RotMatrixElements2ExtEulerZXY(T m12, T m13, T m21, T m22, T m23, T m32, T m33, Vector< T > *vct=NULL)
Definition Rotation.h:941
double Sin_Tolerance
sinθ==0
Definition Tolerance.cpp:23
Quaternion< T > ExtEulerZYX2Quaternion(Vector< T > e)
Definition Rotation.h:237
Vector< T > RotMatrix2ExtEulerXZY(Matrix< T > mtx, Vector< T > *vct=NULL)
Definition Rotation.h:1033
Vector< T > RotMatrix2ExtEulerZYX(Matrix< T > mtx, Vector< T > *vct)
Definition Rotation.h:1017
Vector< T > VectorInvRotation(Vector< T > v, Quaternion< T > q)
Definition Rotation.h:1207
Quaternion< T > ExtEulerYZX2Quaternion(Vector< T > e)
Definition Rotation.h:239
Vector< T > Quaternion2ExtEulerYXZ(Quaternion< T > qut, Vector< T > *vct=NULL)
Definition Rotation.h:1144
Vector< T > Quaternion2ExtEulerXZY(Quaternion< T > qut, Vector< T > *vct=NULL)
Definition Rotation.h:1122
Vector< T > Quaternion2ExtEulerYZX(Quaternion< T > qut, Vector< T > *vct=NULL)
Definition Rotation.h:1133
Quaternion< T > ExtEulerXZY2Quaternion(Vector< T > e)
Definition Rotation.h:238
Vector< T > RotMatrixElements2ExtEulerZYX(T m11, T m12, T m13, T m21, T m23, T m31, T m33, Vector< T > *vct=NULL)
Definition Rotation.h:713
Quaternion< T > SlerpQuaternion(Quaternion< T > qa, Quaternion< T > qb, T t)
Definition Rotation.h:1369
Quaternion< T > V2VQuaternion(Vector< T > a, Vector< T > b)
Definition Rotation.h:1275
Quaternion< T > VPPQuaternion(Vector< T > a, Vector< T > b, Vector< T > c)
Definition Rotation.h:1331
Quaternion< T > RotMatrix2Quaternion(Matrix< T > mtx)
Definition Rotation.h:1167
Vector< T > RotMatrix2ExtEulerYZX(Matrix< T > mtx, Vector< T > *vct=NULL)
Definition Rotation.h:1049
Quaternion< T > PPPQuaternion(Vector< T > a, Vector< T > b, Vector< T > c)
Definition Rotation.h:1320
Vector< T > RotMatrixElements2ExtEulerXZY(T m11, T m12, T m13, T m21, T m22, T m23, T m31, Vector< T > *vct=NULL)
Definition Rotation.h:770
Matrix< T > operator-(const Matrix< T > a)
Definition Matrix++.h:378
Matrix< T > ExtEulerZYX2RotMatrix(Vector< T > eul)
Definition Rotation.h:529
Vector< T > RotMatrixElements2ExtEulerYZX(T m11, T m12, T m13, T m21, T m22, T m31, T m32, Vector< T > *vct=NULL)
Definition Rotation.h:827
Vector< T > Quaternion2ExtEulerZYX(Quaternion< T > qut, Vector< T > *vct=NULL)
Definition Rotation.h:1111
Matrix< T > ExtEulerYZX2RotMatrix(Vector< T > eul)
Definition Rotation.h:579
Matrix< T > ExtEulerXYZ2RotMatrix(Vector< T > eul)
Definition Rotation.h:504
Vector< T > RotMatrixElements2ExtEulerXYZ(T m11, T m12, T m13, T m21, T m31, T m32, T m33, Vector< T > *vct=NULL)
Definition Rotation.h:656