1 
2 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
3  *                                                                     *
4  *                       SIMPLE QUATERNION LIBRARY                     *
5  *                       version 1.1.0                                 *
6  *                       by Melinda Green                              *
7  *                       Mindscape, Inc.                               *
8  *                       January 1996                                  *
9  *                                                                     *
10  * DESCRIPTION                                                         *
11  *    Implements a quaternion class called "SQuat".                    *
12  *    A quaternion represents a rotation about an axis.                *
13  *    Squats can be concatenated together via the '*' and '*='         *
14  *    operators.                                                       *
15  *                                                                     *
16  *    SQuats operate in a left handed coordinate system (i.e. positive *
17  *    Z is coming out of the screen). The direction of a rotation by   *
18  *    a positive value follows the right-hand-rule meaning that if the *
19  *    thumb of your right hand is pointing along the axis of rotation, *
20  *    the rotation is in the direction that your fingers curl.         *
21  *                                                                     *
22  *    Simple 3D vector and matrix classes are also defined mostly as   *
23  *    ways to get 3D data into and out of quaternions. Methods for     *
24  *    matrix multiplication, inversion, etc. are purposely not         *
25  *    implemented because they are fully covered in vec.h the vector   *
26  *    macro library which will work with these vector and matrix       *
27  *    classes and with any other objects that can be indexed into.     *
28  *                                                                     *
29  *    The GetAxis and GetRotation methods extract the current axis and *
30  *    rotation in radians.  A rotation matrix can also be extracted    *
31  *    via the Matrix3 constructor which takes a SQuat argument.        *
32  *    A SQuat can also be initialized from a rotation matrix and       *
33  *    thereby extract its axis of rotation and amount.                 *
34  *                                                                     *
35  *    The GetHomoAxis and GetHomoRoation methods return the raw values *
36  *    stored in a SQuat which have no useful geometric interpretation  *
37  *    and are probably only useful to the application programmer       *
38  *    wanting to archive and restore SQuats as quickly as possible.    *
39  *    When reconstructing a SQuat from homogenous values, use the      *
40  *    five-value constructor and pass a non-zero "homo-vals" flag.     *
41  *    Otherwise, that flag should always be allowed to default to      *
42  *    zero.                                                            *
43  *                                                                     *
44  * BUGS                                                                *
45  *    Constructing from a matrix is only partially tested.             *
46  *                                                                     *
47 \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
48 
49 #ifndef SQUAT
50 #define SQUAT
51 
52 #ifndef DTOR
53 #   define DTOR(d) ((d) * 3.1415926535 / 180)
54 #endif
55 
56 /*
57  * A simple array of three doubles that can be indexed into.
58  */
59 class Vector3
60 {
61   public:
62     Vector3 ();
63     Vector3     (double x, double y, double z);
64     const double &operator[] (long i)const
65         {
66             return elements[i];
67         }
68     double     &operator[] (long i)
69         {
70             return elements[i];
71         }
72     double      Length() const;
73     Vector3     Normal() const;
74   private:
75     double elements[3];
76 };
77 
78 
79 class SQuat
80 {
81   public:
82     SQuat (const Vector3 &axis, double rotation, int homo_vals = 0);
83     SQuat       (const SQuat &);
84     SQuat       (const class Matrix3 &);
85     SQuat       (double x, double y, double z, double r, int homo_vals = 0);
86     SQuat operator *(const SQuat &)const;
87     SQuat      &operator *= (const SQuat &);
88     double      GetRotation() const;
89     void        GetAxis(Vector3 &v) const;  // fastest way to extraxt axis
90     Vector3     GetAxis() const;    // for convienience. Only a touch slower
91     double      GetHomoRotation() const;
92     void        GetHomoAxis(Vector3 &v) const;
93   private:
94     void InitFromVector(const Vector3 &, double);
95     Vector3     axis;
96     double      rot;
97 };
98 
99 
100 class Matrix3
101 {
102   public:
103     Matrix3 ();
104     Matrix3     (const Vector3 &, const Vector3 &, const Vector3 &);
105     Matrix3     (const Matrix3 &);
106     Matrix3     (const SQuat &);
107     const Vector3 &operator[] (long i)const
108         {
109             return rows[i];
110         }
111     Vector3    &operator[] (long i)
112         {
113             return rows[i];
114         }
115   private:
116     Vector3 rows[3];
117 };
118 
119 #endif
120