Newer
Older
Gigg, Martyn Anthony
committed
#ifndef MANTID_KERNEL_QUAT_H_
#define MANTID_KERNEL_QUAT_H_
Gigg, Martyn Anthony
committed
#include "MantidKernel/DllConfig.h"
#include <string>
#include <vector>
namespace Mantid {
namespace Kernel {
// Forward declarations
class V3D;
template <class T> class Matrix;
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
/** @class Quat Quat.h Geometry/Quat.h
@brief Class for quaternions
@version 1.0
@author Laurent C Chapon, ISIS RAL
@date 10/10/2007
Templated class for quaternions.
Quaternions are the 3D generalization of complex numbers
Quaternions are used for roations in 3D spaces and
often implemented for computer graphics applications.
Quaternion can be written q=W+ai+bj+ck where
w is the scalar part, and a, b, c the 3 imaginary parts.
Quaternion multiplication is non-commutative.<br>
i*j=-j*i=k<br>
j*k=-k*j=i<br>
k*i=-i*k=j<br>
Rotation of an angle theta around a normalized axis (u,v,w) can be simply
written W=cos(theta/2), a=u*sin(theta/2), b=v*sin(theta/2), c=w*sin(theta/2)
This class support all arithmetic operations for quaternions
Copyright © 2007 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
National Laboratory & European Spallation Source
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your ption) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
*/
class MANTID_KERNEL_DLL Quat {
public:
Quat();
// direct quat definition
Quat(const double _w, const double _a, const double _b, const double _c);
// * Construct a Quat between two vectors;
// * The angle between them is defined differently from usual if vectors are
// not unit or the same length vectors, so quat would be not consistent
Quat(const V3D &rX, const V3D &rY, const V3D &rZ);
//! Set quaternion form an angle in degrees and an axis
Quat(const double _deg, const V3D &_axis);
// set a quaternion from a rotational matrix;
Quat(const Matrix<double> &RotMat);
void operator()(const Quat &);
void operator()(const double ww, const double aa, const double bb,
const double cc);
void operator()(const double angle, const V3D &);
void operator()(const V3D &rX, const V3D &rY, const V3D &rZ);
void set(const double ww, const double aa, const double bb, const double cc);
void setAngleAxis(const double _deg, const V3D &_axis);
void getAngleAxis(double &_deg, double &_ax0, double &_ax1,
double &ax2) const;
std::vector<double> getEulerAngles(const std::string &convention) const;
/// Set the rotation (both don't change rotation axis)
void setRotation(const double deg);
//! Norm of a quaternion
double len() const;
//! Norm squared
double len2() const;
//! Re-initialize to identity
void init();
//! Normalize
void normalize();
//! Take the complex conjugate
void conjugate();
//! Inverse a quaternion (in the sense of rotation inversion)
void inverse();
//! Is the quaternion representing a null rotation
bool isNull(const double tolerance = 0.001) const;
//! Convert quaternion rotation to an OpenGL matrix [4x4] matrix
//! stored as an linear array of 16 double
//! The function glRotated must be called
//! returns the rotation matrix defined by this quaternion as an 9-point
// vector representing M33 matrix
//! (m33 is not used at the moment), if check_normalisation selected, verify
// if the mod(quat) is indeed == 1 and throws otherwise.
std::vector<double> getRotation(bool check_normalisation = false,
bool throw_on_errors = false) const;
//! Convert GL Matrix into Quat
//! Convert usual 3D rotation matrix into quat; Will throw if matirix is not
// rotational;
void setQuat(const Matrix<double> &rMat);
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
//! Rotate a vector
void rotate(V3D &) const;
//! Taking two points defining a cuboid bounding box (xmin,ymin,zmin) and
//(xmax,ymax,zmax)
// which means implicitly that the cube edges are parallel to the axes,
// find the smallest bounding box with the edges also parallel to the axes
// after rotation of the object.
void rotateBB(double &xmin, double &ymin, double &zmin, double &xmax,
double &ymax, double &zmax) const;
//! Overload operators
Quat operator+(const Quat &) const;
Quat &operator+=(const Quat &);
Quat operator-(const Quat &) const;
Quat &operator-=(const Quat &);
Quat operator*(const Quat &) const;
Quat &operator*=(const Quat &);
bool operator==(const Quat &) const;
bool operator!=(const Quat &) const;
const double &operator[](int) const;
double &operator[](int);
/** @name Element access. */
//@{
/// Access the real part
inline double real() const { return w; }
/// Access the coefficient of i
inline double imagI() const { return a; }
/// Access the coefficient of j
inline double imagJ() const { return b; }
/// Access the coefficient of k
inline double imagK() const { return c; }
//@}
void printSelf(std::ostream &) const;
void readPrinted(std::istream &);
std::string toString() const;
void fromString(const std::string &str);
private:
/// Internal value
double w;
/// Internal value
double a;
/// Internal value
double b;
/// Internal value
double c;
};
MANTID_KERNEL_DLL std::ostream &operator<<(std::ostream &, const Quat &);
MANTID_KERNEL_DLL std::istream &operator>>(std::istream &, Quat &q);
} // Namespace Mantid
Gigg, Martyn Anthony
committed
} // Namespace Kernel
Gigg, Martyn Anthony
committed
#endif /*MANTID_KERNEL_QUAT_H_*/