-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathQuaternion.H
109 lines (87 loc) · 3.45 KB
/
Quaternion.H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//
// $Id: Quaternion.H,v 1.7 2000-11-22 00:23:45 vince Exp $
//
// ---------------------------------------------------------------
// Quaternion.H
// ---------------------------------------------------------------
#ifndef _AMR_QUATERNION_H_
#define _AMR_QUATERNION_H_
#include "REAL.H"
#include "Point.H"
/***************************************************************************
A quaternion represents a rotation of a rigid body in Euclidean
three-dimensional space. (These quaternions all are normalized
so that the sum of the squares of the components is one.)
If the rotation is counterclockwise by an angle alpha about axis n,
then the corresponding quaternion is
[ cos(alpha/2), sin(alpha/2) n ]
Multiplication of normalized quaternions corresponds to composition of
these rotations: q * r means do rotation r first, then q.
The operator *= does right multiplication by the argument, so q *= r
means q = q*r . This seems to be more natural for the usual applications
where r is an increment which is successively applied to a position q.
***************************************************************************/
class AmrQuaternion
{
Real w, x, y, z;
public:
AmrQuaternion() { w=1.; x=y=z=0.; } // The identity rotation
AmrQuaternion(Real W, Real X, Real Y, Real Z) { w=W; x=X; y=Y; z=Z; }
AmrQuaternion(Real, Real, Real, Real, Real, Real);
//returns a quaternion that rotates p1 to p2
AmrQuaternion(const AmrSpherePoint &p1, const AmrSpherePoint &p2);
AmrQuaternion operator *(const AmrQuaternion &q) const;//right-mult by q
AmrQuaternion operator /(const AmrQuaternion &q) const;//right-mult by q^-1
AmrQuaternion operator *=(const AmrQuaternion &q); //right-mult by q
AmrQuaternion operator /=(const AmrQuaternion &q); //right-mult by q^-1
friend AmrQuaternion inverse(const AmrQuaternion &q);// inverse
Real InfNorm() const;
void tomatrix( Real m[4][4] ) const;
Real QW() const { return w; }
Real QX() const { return x; }
Real QY() const { return y; }
Real QZ() const { return z; }
friend ostream& operator<<( ostream &s, const AmrQuaternion &q);
};
inline AmrQuaternion AmrQuaternion::operator *(const AmrQuaternion &q) const
{
return AmrQuaternion( w*q.w - x*q.x - y*q.y - z*q.z,
x*q.w + w*q.x + y*q.z - z*q.y,
y*q.w + w*q.y + z*q.x - x*q.z,
z*q.w + w*q.z + x*q.y - y*q.x );
}
inline AmrQuaternion AmrQuaternion::operator /(const AmrQuaternion &q) const
{
return AmrQuaternion( w*q.w + x*q.x + y*q.y + z*q.z,
x*q.w - w*q.x - y*q.z + z*q.y,
y*q.w - w*q.y - z*q.x + x*q.z,
z*q.w - w*q.z - x*q.y + y*q.x );
}
inline AmrQuaternion AmrQuaternion::operator *=(const AmrQuaternion &q)
{
Real ww = w*q.w - x*q.x - y*q.y - z*q.z;
Real xx = x*q.w + w*q.x + y*q.z - z*q.y;
Real yy = y*q.w + w*q.y + z*q.x - x*q.z;
Real zz = z*q.w + w*q.z + x*q.y - y*q.x;
w=ww; x=xx; y=yy; z=zz;
return *this;
}
inline AmrQuaternion AmrQuaternion::operator /=(const AmrQuaternion &q)
{
Real ww = w*q.w + x*q.x + y*q.y + z*q.z;
Real xx = x*q.w - w*q.x - y*q.z + z*q.y;
Real yy = y*q.w - w*q.y - z*q.x + x*q.z;
Real zz = z*q.w - w*q.z - x*q.y + y*q.x;
w=ww; x=xx; y=yy; z=zz;
return *this;
}
inline AmrQuaternion inverse(const AmrQuaternion &q)
{
return AmrQuaternion( q.w, -q.x, -q.y, -q.z );
}
inline ostream& operator << ( ostream &s, const AmrQuaternion &q)
{
return s << "AmrQuaternion( " << q.w << " , " << q.x << " , "
<< q.y << " , " << q.z << " )";
}
#endif // ndef _AMR_QUATERNION_H_