33 #ifndef __VMML__QUATERNION__HPP__ 34 #define __VMML__QUATERNION__HPP__ 36 #include <vmmlib/types.hpp> 37 #include <vmmlib/vector.hpp> 45 #include <type_traits> 67 typename std::enable_if<M >= 3>::type* = 0);
72 bool equals(
const Quaternion& other,
73 T tolerance = std::numeric_limits<T>::epsilon())
const;
75 T x()
const {
return array[0]; }
76 T y()
const {
return array[1]; }
77 T z()
const {
return array[2]; }
78 T w()
const {
return array[3]; }
91 Quaternion getConjugate()
const;
102 Quaternion& operator=(
const Quaternion& other);
120 Quaternion operator*(T a)
const;
121 Quaternion operator/(T a)
const;
123 void operator*=(T a);
124 void operator/=(T a);
127 friend std::ostream& operator<<(std::ostream& os,
const Quaternion& q)
129 const std::ios::fmtflags flags = os.flags();
130 const int prec = os.precision();
132 os.setf(std::ios::right, std::ios::adjustfield);
135 os <<
"( " << std::setw(10) << q.x() <<
" " << std::setw(10) << q.y()
136 <<
" " << std::setw(10) << q.z() <<
" " << std::setw(10) << q.w()
149 #include <vmmlib/matrix.hpp> 155 template <
typename T>
158 return p.array[3] * q.array[3] + p.array[0] * q.array[0] +
159 p.array[1] * q.array[1] + p.array[2] * q.array[2];
162 template <
typename T>
165 return vector<3, T>(p.array[1] * q.array[2] - p.array[2] * q.array[1],
166 p.array[2] * q.array[0] - p.array[0] * q.array[2],
167 p.array[0] * q.array[1] - p.array[1] * q.array[0]);
171 template <
typename T>
180 template <
typename T>
183 typename std::enable_if<M >= 3>::type*)
185 const T trace = rot(0, 0) + rot(1, 1) + rot(2, 2) + T(1);
186 static const T TRACE_EPSILON = 1e-5;
189 if (trace > TRACE_EPSILON)
191 T s = 0.5 / std::sqrt(trace);
192 array[0] = rot(2, 1) - rot(1, 2);
195 array[1] = rot(0, 2) - rot(2, 0);
198 array[2] = rot(1, 0) - rot(0, 1);
205 const vector<3, T> diag(rot(0, 0), rot(1, 1), rot(2, 2));
206 const size_t largest = diag.find_max_index();
212 0.5 / std::sqrt(T(1) + rot(0, 0) - rot(1, 1) - rot(2, 2));
215 array[1] = rot(0, 1) + rot(1, 0);
218 array[2] = rot(0, 2) + rot(2, 0);
221 array[3] = rot(1, 2) - rot(2, 1);
224 else if (largest == 1)
227 0.5 / std::sqrt(T(1) + rot(1, 1) - rot(0, 0) - rot(2, 2));
228 array[0] = rot(0, 1) + rot(1, 0);
233 array[2] = rot(1, 2) + rot(2, 1);
236 array[3] = rot(0, 2) - rot(2, 0);
240 else if (largest == 2)
243 0.5 / std::sqrt(T(1) + rot(2, 2) - rot(0, 0) - rot(1, 1));
244 array[0] = rot(0, 2) + rot(2, 0);
247 array[1] = rot(1, 2) + rot(2, 1);
252 array[3] = rot(0, 1) - rot(1, 0);
257 throw std::runtime_error(
"no clue why, but should not get here");
262 template <
typename T>
266 const T sinAngle2 = std::sin(angle * 0.5);
267 array[0] = axis.x() * sinAngle2;
268 array[1] = axis.y() * sinAngle2;
269 array[2] = axis.z() * sinAngle2;
270 array[3] = std::cos(angle * 0.5);
273 template <
typename T>
276 return std::abs(array[0] - other.array[0]) <= tolerance &&
277 std::abs(array[1] - other.array[1]) <= tolerance &&
278 std::abs(array[2] - other.array[2]) <= tolerance &&
279 std::abs(array[3] - other.array[3]) <= tolerance;
282 template <
typename T>
285 return array[0] == rhs.array[0] && array[1] == rhs.array[1] &&
286 array[2] == rhs.array[2] && array[3] == rhs.array[3];
289 template <
typename T>
295 template <
typename T>
298 return Quaternion<T>(-array[0], -array[1], -array[2], array[3]);
301 template <
typename T>
304 return std::sqrt(absSquare());
307 template <
typename T>
310 return array[0] * array[0] + array[1] * array[1] + array[2] * array[2] +
314 template <
typename T>
318 const T tmp = T(1) / absSquare();
322 template <
typename T>
329 this->operator*=(len);
336 template <
typename T>
339 return Quaternion(array[0] + rhs.array[0], array[1] + rhs.array[1],
340 array[2] + rhs.array[2], array[3] + rhs.array[3]);
343 template <
typename T>
346 return Quaternion(array[0] - rhs.array[0], array[1] - rhs.array[1],
347 array[2] - rhs.array[2], array[3] - rhs.array[3]);
351 template <
typename T>
360 template <
typename T>
365 const T& a_ = array[3];
366 const T& b_ = array[0];
367 const T& c = array[1];
368 const T& d = array[2];
369 const T& _x = q.array[3];
370 const T& _y = q.array[0];
371 const T& _z = q.array[1];
372 const T& _w = q.array[2];
374 const T tmp_00 = (d - c) * (_z - _w);
375 const T tmp_01 = (a_ + b_) * (_x + _y);
376 const T tmp_02 = (a_ - b_) * (_z + _w);
377 const T tmp_03 = (c + d) * (_x - _y);
378 const T tmp_04 = (d - b_) * (_y - _z);
379 const T tmp_05 = (d + b_) * (_y + _z);
380 const T tmp_06 = (a_ + c) * (_x - _w);
381 const T tmp_07 = (a_ - c) * (_x + _w);
382 const T tmp_08 = tmp_05 + tmp_06 + tmp_07;
383 const T tmp_09 = 0.5 * (tmp_04 + tmp_08);
385 array[0] = tmp_01 + tmp_09 - tmp_08;
386 array[1] = tmp_02 + tmp_09 - tmp_07;
387 array[2] = tmp_03 + tmp_09 - tmp_06;
388 array[3] = tmp_00 + tmp_09 - tmp_05;
391 template <
typename T>
394 return Quaternion(-array[0], -array[1], -array[2], -array[3]);
397 template <
typename T>
400 array[0] += q.array[0];
401 array[1] += q.array[1];
402 array[2] += q.array[2];
403 array[3] += q.array[3];
406 template <
typename T>
409 array[0] -= q.array[0];
410 array[1] -= q.array[1];
411 array[2] -= q.array[2];
412 array[3] -= q.array[3];
419 template <
typename T>
422 return Quaternion(array[0] * a_, array[1] * a_, array[2] * a_,
426 template <
typename T>
430 throw std::runtime_error(
"Division by zero.");
433 return Quaternion(array[0] * a_, array[1] * a_, array[2] * a_,
437 template <
typename T>
446 template <
typename T>
450 throw std::runtime_error(
"Division by zero");
456 template <
typename T>
459 const T w2 = array[3] * array[3];
460 const T x2 = array[0] * array[0];
461 const T y2 = array[1] * array[1];
462 const T z2 = array[2] * array[2];
463 const T wx = array[3] * array[0];
464 const T wy = array[3] * array[1];
465 const T wz = array[3] * array[2];
466 const T xy = array[0] * array[1];
467 const T xz = array[0] * array[2];
468 const T yz = array[1] * array[2];
471 matrix(0, 0) = w2 + x2 - y2 - z2;
472 matrix(0, 1) = 2. * (xy - wz);
473 matrix(0, 2) = 2. * (xz + wy);
474 matrix(1, 0) = 2. * (xy + wz);
475 matrix(1, 1) = w2 - x2 + y2 - z2;
476 matrix(1, 2) = 2. * (yz - wx);
477 matrix(2, 0) = 2. * (xz - wy);
478 matrix(2, 1) = 2. * (yz + wx);
479 matrix(2, 2) = w2 - x2 - y2 + z2;
483 template <
typename T>
486 ::memcpy(array, other.array, 4 *
sizeof(T));
bool equals(const Quaternion &other, T tolerance=std::numeric_limits< T >::epsilon()) const
bool operator==(const Quaternion &a) const
Matrix< 3, 3, T > getRotationMatrix() const
Quaternion()
Construct an identity quaternion.
Quaternion operator-() const
bool operator!=(const Quaternion &a) const
Matrix with R rows and C columns of element type T.
Quaternion inverse() const