Easy3D 2.6.1
Loading...
Searching...
No Matches
quat.h
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
38
39#ifndef EASY3D_CORE_QUATERNION_H
40#define EASY3D_CORE_QUATERNION_H
41
42#include <easy3d/core/constant.h>
43#include <easy3d/core/vec.h>
44#include <easy3d/core/mat.h>
45
46
47namespace easy3d {
48
104
105 template <typename FT>
106 class Quat
107 {
108 public:
109 typedef Vec<3, FT> Vec3;
111
112 public:
115 {
116 _q[0] = _q[1] = _q[2] = FT(0); _q[3] = FT(1);
117 }
118
120 explicit Quat(const Mat3<FT>& m)
121 {
123 }
124
126 Quat(const Vec3& axis, FT angle)
127 {
129 }
130
136 Quat(const Vec3& from, const Vec3& to);
137
144 Quat(FT q0, FT q1, FT q2, FT q3)
145 { _q[0]=q0; _q[1]=q1; _q[2]=q2; _q[3]=q3; }
146
148 Quat(const thisclass& Q)
149 { for (int i=0; i<4; ++i) _q[i] = Q._q[i]; }
150
153 for (int i=0; i<4; ++i)
154 _q[i] = Q._q[i];
155 return (*this);
156 }
157
162 void set_axis_angle(const Vec3& axis, FT angle);
163
165 void set_value(FT q0, FT q1, FT q2, FT q3)
166 { _q[0]=q0; _q[1]=q1; _q[2]=q2; _q[3]=q3; }
167
175
180 void set_from_rotated_basis(const Vec3& X, const Vec3& Y, const Vec3& Z);
181
186 Vec3 axis() const;
187
193 FT angle() const;
194
198 void get_axis_angle(Vec3& axis, FT& angle) const;
199
203 FT operator[](int i) const { return _q[i]; }
204
206 FT& operator[](int i) { return _q[i]; }
207
208 /* Rotation computations */
209
220 friend Quat operator*(const Quat& a, const Quat& b)
221 {
222 return Quat(
223 a._q[3]*b._q[0] + b._q[3]*a._q[0] + a._q[1]*b._q[2] - a._q[2]*b._q[1],
224 a._q[3]*b._q[1] + b._q[3]*a._q[1] + a._q[2]*b._q[0] - a._q[0]*b._q[2],
225 a._q[3]*b._q[2] + b._q[3]*a._q[2] + a._q[0]*b._q[1] - a._q[1]*b._q[0],
226 a._q[3]*b._q[3] - b._q[0]*a._q[0] - a._q[1]*b._q[1] - a._q[2]*b._q[2]
227 );
228 }
229
236 Quat& operator*=(const Quat &q) {
237 *this = (*this)*q;
238 return *this;
239 }
240
245 friend Vec3 operator*(const Quat& q, const Vec3& v) { return q.rotate(v); }
246
251 Vec3 rotate(const Vec3& v) const;
252
257 Vec3 inverse_rotate(const Vec3& v) const {
258 return inverse().rotate(v);
259 }
260
266 Quat inverse() const { return Quat(-_q[0], -_q[1], -_q[2], _q[3]); }
267
272 void invert() { _q[0] = -_q[0]; _q[1] = -_q[1]; _q[2] = -_q[2]; }
273
282 void negate() { invert(); _q[3] = -_q[3]; }
283
285 FT length() const {
286 return std::sqrt(_q[0] * _q[0] + _q[1] * _q[1] + _q[2] * _q[2] + _q[3] * _q[3]);
287 }
288
296 const FT norm = std::sqrt(_q[0] * _q[0] + _q[1] * _q[1] + _q[2] * _q[2] + _q[3] * _q[3]);
297 for (int i=0; i<4; ++i)
298 _q[i] /= norm;
299 return norm;
300 }
301
306 Quat normalized() const {
307 FT Q[4];
308 const FT norm = std::sqrt(_q[0] * _q[0] + _q[1] * _q[1] + _q[2] * _q[2] + _q[3] * _q[3]);
309 for (int i=0; i<4; ++i)
310 Q[i] = _q[i] / norm;
311 return Quat(Q[0], Q[1], Q[2], Q[3]);
312 }
313
319
322
324
332 static Quat slerp(const Quat<FT>& a, const Quat<FT>& b, FT t, bool allowFlip = true);
333
339 static Quat squad(const Quat<FT>& a, const Quat<FT>& tgA, const Quat<FT>& tgB, const Quat<FT>& b, FT t);
340
342 static FT dot(const Quat<FT>& a, const Quat<FT>& b) { return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; }
343
348
350 static Quat ln_dif(const Quat<FT>& a, const Quat<FT>& b);
355 static Quat squad_tangent(const Quat<FT>& before, const Quat<FT>& center, const Quat<FT>& after);
356
367
368 //data intentionally left public to allow q.x ...
369 public:
370 /* The internal data representation is private, use operator[] to access values. */
371 union {
372 struct { FT x; FT y; FT z; FT w; };
373 FT _q[4];
374 };
375 };
376
377 template <typename FT> std::ostream& operator<<(std::ostream& os, const Quat<FT>& q);
378 template <typename FT> std::istream& operator>>(std::istream& is, Quat<FT>& q);
379
380
381 //-------------- implementation -----------------
382
383
384 template <typename FT>
385 Quat<FT>::Quat(const Vec3& from, const Vec3& to)
386 {
387 const FT fromSqNorm = from.length2();
388 const FT toSqNorm = to.length2();
389 // Identity Quaternion when one vector is null
390 if ((fromSqNorm < epsilon<FT>()) || (toSqNorm < epsilon<FT>()))
391 {
392 _q[0] = _q[1] = _q[2] = 0.0;
393 _q[3] = 1.0;
394 }
395 else
396 {
397 Vec3 axis = cross(from, to);
398 const FT axisSqNorm = axis.length2();
399
400 // Aligned vectors, pick any axis, not aligned with from or to
401 if (axisSqNorm < epsilon<FT>())
402 axis = orthogonal(from);
403
404 FT angle = std::asin(std::sqrt(axisSqNorm / (fromSqNorm * toSqNorm)));
405
406 if (easy3d::dot(from, to) < 0.0)
407 angle = FT(M_PI - angle);
408
410 }
411 }
412
413 template <typename FT>
415 {
416 const FT norm = axis.length();
417 if (norm < 1E-8)
418 {
419 // Null rotation
420 _q[0] = FT(0); _q[1] = FT(0); _q[2] = FT(0); _q[3] = FT(1);
421 }
422 else
423 {
424 const FT sin_half_angle = std::sin(angle / 2.0f);
425 _q[0] = sin_half_angle*axis[0] / norm;
426 _q[1] = sin_half_angle*axis[1] / norm;
427 _q[2] = sin_half_angle*axis[2] / norm;
428 _q[3] = (FT)std::cos(angle / 2.0f);
429 }
430 }
431
432
433 template <typename FT>
434 typename Quat<FT>::Vec3 Quat<FT>::rotate(const Vec3& v) const
435 {
436 const FT q00 = FT(2.0l * _q[0] * _q[0]);
437 const FT q11 = FT(2.0l * _q[1] * _q[1]);
438 const FT q22 = FT(2.0l * _q[2] * _q[2]);
439
440 const FT q01 = FT(2.0l * _q[0] * _q[1]);
441 const FT q02 = FT(2.0l * _q[0] * _q[2]);
442 const FT q03 = FT(2.0l * _q[0] * _q[3]);
443
444 const FT q12 = FT(2.0l * _q[1] * _q[2]);
445 const FT q13 = FT(2.0l * _q[1] * _q[3]);
446
447 const FT q23 = FT(2.0l * _q[2] * _q[3]);
448
449 return Vec3(
450 FT((1.0 - q11 - q22)*v[0] + (q01 - q23)*v[1] + (q02 + q13)*v[2]),
451 FT((q01 + q23)*v[0] + (1.0 - q22 - q00)*v[1] + (q12 - q03)*v[2]),
452 FT((q02 - q13)*v[0] + (q12 + q03)*v[1] + (1.0 - q11 - q00)*v[2]));
453 }
454
455 template <typename FT>
457 {
458 // see http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
459 // Compute one plus the trace of the matrix
460 const FT onePlusTrace = FT(1.0) + m(0, 0) + m(1, 1) + m(2, 2);
461
462 if (onePlusTrace > 1E-5) {
463 // Direct computation
464 const FT s = std::sqrt(onePlusTrace) * FT(2.0);
465 _q[0] = (m(2, 1) - m(1, 2)) / s;
466 _q[1] = (m(0, 2) - m(2, 0)) / s;
467 _q[2] = (m(1, 0) - m(0, 1)) / s;
468 _q[3] = FT(0.25) * s;
469 }
470 else
471 {
472 // Computation depends on major diagonal term
473 if ((m(0, 0) > m(1, 1)) && (m(0, 0) > m(2, 2))) {
474 const FT s = std::sqrt(FT(1.0) + m(0, 0) - m(1, 1) - m(2, 2)) * FT(2.0);
475 _q[0] = FT(0.25) * s;
476 _q[1] = (m(0, 1) + m(1, 0)) / s;
477 _q[2] = (m(0, 2) + m(2, 0)) / s;
478 _q[3] = (m(1, 2) - m(2, 1)) / s;
479 }
480 else if (m(1, 1) > m(2, 2)) {
481 const FT s = std::sqrt(FT(1.0) + m(1, 1) - m(0, 0) - m(2, 2)) * FT(2.0);
482 _q[0] = (m(0, 1) + m(1, 0)) / s;
483 _q[1] = FT(0.25) * s;
484 _q[2] = (m(1, 2) + m(2, 1)) / s;
485 _q[3] = (m(0, 2) - m(2, 0)) / s;
486 }
487 else {
488 const FT s = std::sqrt(FT(1.0) + m(2, 2) - m(0, 0) - m(1, 1)) * FT(2.0);
489 _q[0] = (m(0, 2) + m(2, 0)) / s;
490 _q[1] = (m(1, 2) + m(2, 1)) / s;
491 _q[2] = FT(0.25) * s;
492 _q[3] = (m(0, 1) - m(1, 0)) / s;
493 }
494 }
495 normalize();
496 }
497
498 template <typename FT>
499 void Quat<FT>::set_from_rotated_basis(const Vec3& X, const Vec3& Y, const Vec3& Z)
500 {
501 Mat3<FT> m;
502 FT normX = X.length();
503 FT normY = Y.length();
504 FT normZ = Z.length();
505
506 for (int i = 0; i < 3; ++i) {
507 m(i, 0) = X[i] / normX;
508 m(i, 1) = Y[i] / normY;
509 m(i, 2) = Z[i] / normZ;
510 }
511
513 }
514
515 template <typename FT>
517 {
518 // The normalize() is here to prevent failure introduced by numerical error.
519 // We call std::acos(_q[3]), but _q[3] equaling to 1 can actually be e.g., 1.00000012.
520 if (_q[3] > FT(1)) {
521 const_cast<Quat*>(this)->normalize();
522 }
523 angle = FT(2.0) * std::acos(_q[3]);
524 axis = Vec3(_q[0], _q[1], _q[2]);
525 const FT sinus = axis.length();
526 if (sinus > 1E-8)
527 axis = axis / sinus;
528
529 if (angle > M_PI) {
530 angle = 2.0*M_PI - angle;
531 axis = -axis;
532 }
533 }
534
535 template <typename FT>
537 {
538 Vec3 res(_q[0], _q[1], _q[2]);
539 const FT sinus = res.length();
540 if (sinus > 1E-8)
541 res = res / sinus;
542
543 // The normalize() is here to prevent failure introduced by numerical error.
544 // We call std::acos(_q[3]), but _q[3] equaling to 1 can actually be e.g., 1.00000012.
545 if (_q[3] > FT(1)) {
546 const_cast<Quat*>(this)->normalize();
547 }
548 return (std::acos(_q[3]) <= M_PI / 2.0) ? res : -res;
549 }
550
551 template <typename FT>
553 {
554 // The normalize() is here to prevent failure introduced by numerical error.
555 // We call std::acos(_q[3]), but _q[3] equaling to 1 can actually be e.g., 1.00000012.
556 if (_q[3] > FT(1)) {
557 const_cast<Quat*>(this)->normalize();
558 }
559 const FT angle = FT(2.0) * std::acos(_q[3]);
560 return (angle <= M_PI) ? angle : FT(2.0*M_PI - angle);
561 }
562
563
564 //Mat4 quat_to_matrix(const Quat& q)
565 //{
566 // Mat4 M;
567 //
568 // const double x = q.vector()[0];
569 // const double y = q.vector()[1];
570 // const double z = q.vector()[2];
571 // const double w = q.scalar();
572 // const double s = 2 / norm(q);
573 //
574 // M(0, 0) = 1 - s*(y*y + z*z); M(0, 1) = s*(x*y - w*z); M(0, 2) = s*(x*z + w*y); M(0, 3) = 0;
575 // M(1, 0) = s*(x*y + w*z); M(1, 1) = 1 - s*(x*x + z*z); M(1, 2) = s*(y*z - w*x); M(1, 3) = 0;
576 // M(2, 0) = s*(x*z - w*y); M(2, 1) = s*(y*z + w*x); M(2, 2) = 1 - s*(x*x + y*y); M(2, 3) = 0;
577 // M(3, 0) = 0; M(3, 1) = 0; M(3, 2) = 0; M(3, 3) = 1;
578 //
579 // return M;
580 //}
581 //
582 //Mat4 unit_quat_to_matrix(const Quat& q)
583 //{
584 // Mat4 M;
585 //
586 // const double x = q.vector()[0];
587 // const double y = q.vector()[1];
588 // const double z = q.vector()[2];
589 // const double w = q.scalar();
590 //
591 // M(0, 0) = 1 - 2 * (y*y + z*z); M(0, 1) = 2 * (x*y - w*z); M(0, 2) = 2 * (x*z + w*y); M(0, 3) = 0;
592 // M(1, 0) = 2 * (x*y + w*z); M(1, 1) = 1 - 2 * (x*x + z*z); M(1, 2) = 2 * (y*z - w*x); M(1, 3) = 0;
593 // M(2, 0) = 2 * (x*z - w*y); M(2, 1) = 2 * (y*z + w*x); M(2, 2) = 1 - 2 * (x*x + y*y); M(2, 3) = 0;
594 // M(3, 0) = 0; M(3, 1) = 0; M(3, 2) = 0; M(3, 3) = 1;
595 //
596 // return M;
597 //}
598
599
600 template <typename FT>
602 {
603 const FT q00 = FT(2.0l * _q[0] * _q[0]);
604 const FT q11 = FT(2.0l * _q[1] * _q[1]);
605 const FT q22 = FT(2.0l * _q[2] * _q[2]);
606
607 const FT q01 = FT(2.0l * _q[0] * _q[1]);
608 const FT q02 = FT(2.0l * _q[0] * _q[2]);
609 const FT q03 = FT(2.0l * _q[0] * _q[3]);
610
611 const FT q12 = FT(2.0l * _q[1] * _q[2]);
612 const FT q13 = FT(2.0l * _q[1] * _q[3]);
613
614 const FT q23 = FT(2.0l * _q[2] * _q[3]);
615
616 Mat4<FT> m;
617 m(0, 0) = FT(1.0) - q11 - q22;
618 m(0, 1) = q01 - q23;
619 m(0, 2) = q02 + q13;
620
621 m(1, 0) = q01 + q23;
622 m(1, 1) = FT(1.0) - q22 - q00;
623 m(1, 2) = q12 - q03;
624
625 m(2, 0) = q02 - q13;
626 m(2, 1) = q12 + q03;
627 m(2, 2) = FT(1.0) - q11 - q00;
628
629 m(3, 0) = FT(0.0);
630 m(3, 1) = FT(0.0);
631 m(3, 2) = FT(0.0);
632
633 m(0, 3) = FT(0.0);
634 m(1, 3) = FT(0.0);
635 m(2, 3) = FT(0.0);
636 m(3, 3) = FT(1.0);
637
638 return m;
639 }
640
641 template <typename FT>
643 {
644 return inverse().matrix();
645 }
646
647 template <typename FT>
648 Quat<FT> Quat<FT>::slerp(const Quat<FT>& a, const Quat<FT>& b, FT t, bool allowFlip)
649 {
650 FT cosAngle = Quat<FT>::dot(a, b);
651
652 FT c1, c2;
653 // Linear interpolation for close orientations
654 if ((1.0 - std::fabs(cosAngle)) < 0.01)
655 {
656 c1 = FT(1.0) - t;
657 c2 = t;
658 }
659 else
660 {
661 // Spherical interpolation
662 FT angle = std::acos(std::fabs(cosAngle));
663 FT sinAngle = std::sin(angle);
664 c1 = std::sin(angle * (1.0 - t)) / sinAngle;
665 c2 = std::sin(angle * t) / sinAngle;
666 }
667
668 // Use the shortest path
669 if (allowFlip && (cosAngle < 0.0))
670 c1 = -c1;
671
672 return Quat(c1*a[0] + c2*b[0], c1*a[1] + c2*b[1], c1*a[2] + c2*b[2], c1*a[3] + c2*b[3]);
673 }
674
675 template <typename FT>
676 Quat<FT> Quat<FT>::squad(const Quat<FT>& a, const Quat<FT>& tgA, const Quat<FT>& tgB, const Quat<FT>& b, FT t)
677 {
678 Quat<FT> ab = Quat<FT>::slerp(a, b, t);
679 Quat<FT> tg = Quat<FT>::slerp(tgA, tgB, t, false);
680 return Quat<FT>::slerp(ab, tg, 2.0*t*(1.0 - t), false);
681 }
682
683 template <typename FT>
685 {
686 FT len = std::sqrt(_q[0] * _q[0] + _q[1] * _q[1] + _q[2] * _q[2]);
687
688 if (len < 1E-6)
689 return Quat(_q[0], _q[1], _q[2], 0.0);
690 else
691 {
692 // The normalize() is here to prevent failure introduced by numerical error.
693 // We call std::acos(_q[3]), but _q[3] equaling to 1 can actually be e.g., 1.00000012.
694 if (_q[3] > FT(1)) {
695 const_cast<Quat*>(this)->normalize();
696 } FT coef = std::acos(_q[3]) / len;
697 return Quat(_q[0] * coef, _q[1] * coef, _q[2] * coef, 0.0);
698 }
699 }
700
701 template <typename FT>
703 {
704 FT theta = std::sqrt(_q[0] * _q[0] + _q[1] * _q[1] + _q[2] * _q[2]);
705
706 if (theta < 1E-6)
707 return Quat(_q[0], _q[1], _q[2], std::cos(theta));
708 else
709 {
710 FT coef = std::sin(theta) / theta;
711 return Quat(_q[0] * coef, _q[1] * coef, _q[2] * coef, std::cos(theta));
712 }
713 }
714
715 template <typename FT>
716 Quat<FT> Quat<FT>::ln_dif(const Quat& a, const Quat& b)
717 {
718 Quat<FT> dif = a.inverse()*b;
719 dif.normalize();
720 return dif.log();
721 }
722
723 template <typename FT>
724 Quat<FT> Quat<FT>::squad_tangent(const Quat<FT>& before, const Quat<FT>& center, const Quat<FT>& after)
725 {
726 Quat<FT> l1 = Quat<FT>::ln_dif(center, before);
727 Quat<FT> l2 = Quat<FT>::ln_dif(center, after);
728 Quat<FT> e;
729 for (int i = 0; i < 4; ++i)
730 e._q[i] = -0.25 * (l1._q[i] + l2._q[i]);
731 e = center*(e.exp());
732
733 // if (Quat<FT>::dot(e,b) < 0.0)
734 // e.negate();
735
736 return e;
737 }
738
739 template <typename FT>
741 {
742 // The rand() function is not very portable and may not be available on your system.
743 // Add the appropriate include or replace it by another random function in case of problem.
744 FT seed = rand() / (FT)RAND_MAX;
745 FT r1 = std::sqrt(1.0f - seed);
746 FT r2 = std::sqrt(seed);
747 FT t1 = 2.0f * M_PI * (rand() / (FT)RAND_MAX);
748 FT t2 = 2.0f * M_PI * (rand() / (FT)RAND_MAX);
749 return Quat(std::sin(t1)*r1, std::cos(t1)*r1, std::sin(t2)*r2, std::cos(t2)*r2);
750 }
751
753 template <typename FT> inline
754 std::ostream& operator<<(std::ostream& os, const Quat<FT>& Q)
755 {
756 return os << Q[0] << ' ' << Q[1] << ' ' << Q[2] << ' ' << Q[3];
757 }
758
760 template <typename FT> inline
761 std::istream& operator>>(std::istream& is, Quat<FT>& Q) {
762 return is >> Q[0] >> Q[1] >> Q[2] >> Q[3];
763 }
764
766 template <class FT> inline
767 bool has_nan(const Quat<FT>& Q) {
768 for (int i=0; i<4; ++i) {
769 if (std::isnan(Q[i]) || std::isinf(Q[i]))
770 return true;
771 }
772 return false;
773 }
774
775}
776
777
778#endif // EASY3D_CORE_QUATERNION_H
3 by 3 matrix. Extends Mat with 3D-specific functionality and constructors.
Definition mat.h:1844
4 by 4 matrix. Extends Mat with 4D-specific functionality and constructors.
Definition mat.h:2180
The Quaternion class represents 3D rotations and orientations.
Definition quat.h:107
friend Quat operator*(const Quat &a, const Quat &b)
Returns the composition of the a and b rotations. The order is important. When applied to a Vec v (se...
Definition quat.h:220
Quat(const thisclass &Q)
Definition quat.h:148
static Quat ln_dif(const Quat< FT > &a, const Quat< FT > &b)
Returns log(a. inverse() * b). Useful for squad_tangent().
Definition quat.h:716
Quat(const Mat3< FT > &m)
Constructor from rotation matrix. See also set_from_rotation_matrix().
Definition quat.h:120
void set_axis_angle(const Vec3 &axis, FT angle)
Definition quat.h:414
FT length() const
Return the length of the quaternion.
Definition quat.h:285
static Quat squad_tangent(const Quat< FT > &before, const Quat< FT > &center, const Quat< FT > &after)
Returns a tangent Quaternion for center, defined by before and after Quaternions. Useful for smooth s...
Definition quat.h:724
void set_value(FT q0, FT q1, FT q2, FT q3)
Definition quat.h:165
Vec3 inverse_rotate(const Vec3 &v) const
Returns the image of v by the Quaternion inverse() rotation. rotate() performs an inverse transformat...
Definition quat.h:257
Quat inverse() const
Inversion. Returns the inverse Quaternion (inverse rotation). Result has a negated axis() direction a...
Definition quat.h:266
Vec3 rotate(const Vec3 &v) const
Returns the image of v by the Quaternion rotation.
Definition quat.h:434
void set_from_rotated_basis(const Vec3 &X, const Vec3 &Y, const Vec3 &Z)
Set a Quaternion from the three axis of a rotated frame. It actually fills the three columns of a mat...
Definition quat.h:499
float angle() const
FT normalize()
Normalizes the Quaternion coefficients. This method should not need to be called since we only deal w...
Definition quat.h:295
Quat log()
Returns the logarithm of the Quaternion. See also exp().
Definition quat.h:684
FT & operator[](int i)
Bracket operator returning an l-value. i must range in [0..3].
Definition quat.h:206
Quat(const Vec3 &axis, FT angle)
Constructor from rotation axis (non null) and angle (in radians). See also set_axis_angle().
Definition quat.h:126
friend Vec3 operator*(const Quat &q, const Vec3 &v)
Returns the image of v by the rotation q. Same as q.rotate(v).
Definition quat.h:245
void set_from_rotation_matrix(const Mat3< FT > &m)
Set the Quaternion from a (supposedly correct) 3x3 rotation matrix. The matrix is expressed in Europe...
Definition quat.h:456
Mat4< FT > matrix() const
Returns the Quaternion associated 4x4 rotation matrix. Use glMultMatrixf(q.matrix()) to apply the rot...
Definition quat.h:601
Quat normalized() const
Returns a normalized version of the Quaternion.
Definition quat.h:306
void invert()
Inverses the Quaternion (same rotation angle(), but negated axis()).
Definition quat.h:272
Quat & operator=(const thisclass &Q)
Definition quat.h:152
Quat & operator*=(const Quat &q)
Quaternion rotation is composed with q. See operator*(), since this is equivalent to this = this * q.
Definition quat.h:236
Quat(FT q0, FT q1, FT q2, FT q3)
Constructor from the four values of a Quaternion. First three values are axis*std::sin(angle/2) and t...
Definition quat.h:144
void negate()
Negates all the coefficients of the Quaternion. This results in an other representation of the same r...
Definition quat.h:282
Vec< 3, FT > Vec3
3D vector type
Definition quat.h:109
static Quat slerp(const Quat< FT > &a, const Quat< FT > &b, FT t, bool allowFlip=true)
Slerp(Spherical Linear intERPolation) interpolation. Returns the slerp interpolation of Quaternions a...
Definition quat.h:648
Quat(const Vec3 &from, const Vec3 &to)
Constructs a quaternion that will rotate from the from direction to the to direction.
Definition quat.h:385
FT operator[](int i) const
Bracket operator, with a constant return value. i must range in [0..3].
Definition quat.h:203
static thisclass random_quat()
Returns a random unit Quaternion. You can create a randomly directed unit vector using:
Definition quat.h:740
Mat4< FT > inverse_matrix() const
Returns the associated 4x4 inverse rotation matrix. This is simply the matrix() of the inverse().
Definition quat.h:642
static FT dot(const Quat< FT > &a, const Quat< FT > &b)
Returns the "dot" product of a and b: a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3].
Definition quat.h:342
Quat< FT > thisclass
Quaternion type.
Definition quat.h:110
Quat exp()
Returns the exponential of the Quaternion. See also log().
Definition quat.h:702
static Quat squad(const Quat< FT > &a, const Quat< FT > &tgA, const Quat< FT > &tgB, const Quat< FT > &b, FT t)
Returns the slerp interpolation of the two Quaternions a and b, at time t, using tangents tgA and tgB...
Definition quat.h:676
Quat()
Default constructor, builds an identity rotation.
Definition quat.h:114
void get_axis_angle(Vec3 &axis, FT &angle) const
Returns the axis vector and the angle (in radians) of the rotation represented by the Quaternion.
Definition quat.h:516
Base class for vector types. It provides generic functionality for N dimensional vectors.
Definition vec.h:30
T length() const
Returns the length of this vector.
Definition vec.h:115
T length2() const
Returns the squared length of this vector.
Definition vec.h:106
Definition collider.cpp:182
Vec< N, T > normalize(const Vec< N, T > &v)
Computes and returns the normalized vector (Note: the input vector is not modified).
Definition vec.h:299
Vec< 3, T > cross(const Vec< 3, T > &v1, const Vec< 3, T > &v2)
Compute the cross product of two 3D vectors.
Definition vec.h:685
Vec< 3, T > orthogonal(const Vec< 3, T > &v)
Compute a vector that is orthogonal to the given vector.
Definition vec.h:712
FT epsilon()
Function returning the epsilon value for a given type.
std::ostream & operator<<(std::ostream &os, Graph::Vertex v)
Output stream support for Graph::Vertex.
Definition graph.h:1300
Mat< N, N, T > inverse(const Mat< N, N, T > &m)
Returns the inverse of an N x N (square) matrix.
Definition mat.h:1190
std::istream & operator>>(std::istream &is, GenericLine< DIM, FT > &line)
Input stream support for GenericLine.
Definition line.h:183
bool has_nan(const GenericBox< DIM, FT > &box)
Check if the representation of a box has NaN.
Definition box.h:373
FT dot(const std::vector< FT > &, const std::vector< FT > &)
Inner product for vectors.
Definition matrix.h:1834
FT norm(const Matrix< FT > &)
utilities
Definition matrix.h:1455