33template <
class ValueType >
class DLLEXPORT Quaternion{
35 Quaternion(ValueType w = 1.0, ValueType i = 0.0, ValueType j = 0.0, ValueType k = 0.0)
37 im_[0] = i; im_[1] = j; im_[2] = k;
40 Quaternion(ValueType re,
const Pos & im)
43 Quaternion(
const Pos & xAxis,
const Pos & yAxis,
48 Quaternion(
const Quaternion < ValueType > & q) { copy_(q); }
50 Quaternion & operator = (
const Quaternion < ValueType > & q) {
57 const ValueType operator [] (
const size_t i)
const {
58 if (i == 0)
return re_;
else return im_[i - 1];
61 ValueType & operator [] (
const size_t i){
if (i == 0)
return re_;
else return im_[i - 1]; }
63 Quaternion & operator /= (
const ValueType & s) { re_ /= s; im_ /= s;
return *
this;}
64 Quaternion & operator *= (
const ValueType & s) { re_ *= s; im_ /= s;
return *
this;}
66 void createFromAxisAngle(
const Pos & axis,
double angle){
69 double ah = 0.5 * angle;
71 im_ = axis * std::sin(ah);
74 template <
class Matrix >
void rotMatrix(
Matrix & rot)
const {
75 ValueType
x = 2.0 * im_[0],
y = 2.0 * im_[1],
z = 2.0 * im_[2];
77 ValueType wx =
x * re_, wy =
y * re_, wz =
z * re_;
78 ValueType xx =
x * im_[0], xy =
y * im_[0], xz =
z * im_[0];
79 ValueType yy =
y * im_[1], yz =
z * im_[1], zz =
z * im_[2];
81 rot[0][0] = 1.0 - (yy + zz);
85 rot[1][1] = 1.0 - (xx + zz);
89 rot[2][2] = 1.0 - (xx + yy);
92 inline ValueType norm()
const {
return re_ * re_ + im_.distSquared(); }
94 inline ValueType length()
const {
return std::sqrt(norm()); }
96 inline void normalise(){ *
this /= length(); }
98 inline void setRe(
const ValueType re){ re_ = re; }
99 inline ValueType re()
const {
return re_; }
101 inline void setIm(
const Pos & im) { im_ = im; }
102 inline Pos im()
const {
return im_; }
106 void copy_(
const Quaternion < ValueType > & q){ re_ = q.re(); im_ = q.im(); }