30 #ifndef _GranOO_libGeom_QUATERNION_hpp_
31 #define _GranOO_libGeom_QUATERNION_hpp_
35 #include "GranOO3/3rdParty/Eigen/Dense"
36 #include <boost/archive/text_oarchive.hpp>
37 #include <boost/archive/text_iarchive.hpp>
70 static std::string
class_ID() {
return "Quaternion";}
74 static const int N = 4;
101 void set_value(
double q0,
double q1,
double q2,
double q3);
105 const double &
x()
const;
107 const double &
y()
const;
109 const double &
z()
const;
111 const double &
r()
const;
127 template <
typename Axis>
double&
val();
128 template <
typename Axis>
const double&
val()
const;
165 std::string
info()
const;
166 void add_glob(
const std::string&
id);
172 template<
class Archive>
void serialize(Archive & ar,
const unsigned int );
178 #ifndef DOXYGEN_SHOULD_SKIP_THIS
182 template<
class Archive>
185 ar &
x(); ar &
y(); ar &
z(); ar &
coord(3);
189 std::ostream &
operator<< (std::ostream& o,
const Quaternion& q);
190 Quaternion slerp (
const Quaternion& ,
const Quaternion&,
const double& ratio);
191 Quaternion
operator* (
const Quaternion& ,
const Vector & );
192 Quaternion
operator* (
const Vector & ,
const Quaternion &);
193 Quaternion
operator* (
const Quaternion &,
const Quaternion &);
194 Quaternion
operator* (
const Quaternion &,
const double & );
195 Quaternion
operator* (
const double & ,
const Quaternion &);
196 Quaternion
operator+ (
const Quaternion &,
const Quaternion &);
197 Quaternion
operator- (
const Quaternion &,
const Quaternion &);
198 bool operator== (
const Quaternion &,
const Quaternion &);
219 : coord(q0, q1, q2, real){
236 inline const double &
246 inline const double &
256 inline const double &
266 inline const double &
311 template<
typename Axis>
inline
317 template<
typename Axis>
inline
324 double& Quaternion::val<X>() {
329 const double& Quaternion::val<X>()
const {
334 double& Quaternion::val<Y>() {
339 const double& Quaternion::val<Y>()
const {
344 double& Quaternion::val<Z>() {
349 const double& Quaternion::val<Z>()
const {
354 double& Quaternion::val<R>() {
359 const double& Quaternion::val<R>()
const {
378 const float epsilon = 1E-10f;
380 const float fromSqNorm = (float)(from.squared_norm());
381 const float toSqNorm = (float)(to.squared_norm());
383 if ((fromSqNorm < epsilon) || (toSqNorm < epsilon)) {
384 x() =
y() =
z() = 0.;
387 Vector axis = from^to;
388 const float axisSqNorm = (float)(axis.squared_norm());
391 if (axisSqNorm < epsilon) {
392 axis = from.orthogonal_vector();
395 double angle = asin(sqrt(axisSqNorm / (fromSqNorm * toSqNorm)));
408 const double norm = axis.norm();
418 const double sin_half_angle = sin(angle / 2.0);
419 x() = sin_half_angle*axis.x()/
norm;
420 y() = sin_half_angle*axis.y()/
norm;
421 z() = sin_half_angle*axis.z()/
norm;
422 r() = cos(angle / 2.0);
428 const Geom::Vector axis =
get_axis();
429 const double sin_half_angle = sin(angle / 2.0);
430 x() = sin_half_angle*axis.x();
431 y() = sin_half_angle*axis.y();
432 z() = sin_half_angle*axis.z();
433 r() = cos(angle / 2.0);
441 operator<<(std::ostream& o,
const Quaternion& q) {
442 return o << q.x() <<
'\t' << q.y() <<
'\t' << q.z() <<
'\t' << q.r();
447 slerp(
const Quaternion& q0,
const Quaternion& q1,
const double& ratio) {
448 const double one = 1.0 - std::numeric_limits<double>::epsilon();
449 double d = q0.x()*q1.x() + q0.y()*q1.y() + q0.z()*q1.z() + q0.r()*q1.r();
450 double absD = abs(d);
454 scale0 = 1.0 - ratio;
457 double theta = acos(absD);
458 double sinTheta = sin(theta);
459 scale0 = sin((1.0 - ratio) * theta) / sinTheta;
460 scale1 = sin((ratio * theta)) / sinTheta;
465 return Quaternion(scale0 * q0 + scale1 * q1);
471 operator*(
const Quaternion& q1,
const Quaternion& q2) {
472 return Quaternion (q1.r()*q2.x() + q1.x()*q2.r() + q1.y()*q2.z() - q1.z()*q2.y(),
473 q1.r()*q2.y() + q1.y()*q2.r() + q1.z()*q2.x() - q1.x()*q2.z(),
474 q1.r()*q2.z() + q1.z()*q2.r() + q1.x()*q2.y() - q1.y()*q2.x(),
475 q1.r()*q2.r() - q1.x()* q2.x() - q1.y()*q2.y() - q1.z()*q2.z());
480 operator*(
const Quaternion& q,
const Vector& v) {
481 return Quaternion(q.r()*v.x() + q.y()*v.z() - q.z()*v.y(),
482 q.r()*v.y() + q.z()*v.x() - q.x()*v.z(),
483 q.r()*v.z() + q.x()*v.y() - q.y()*v.x(),
484 -v.x()*q.x() - q.y()*v.y() - q.z()*v.z() );
489 operator* (
const Vector& v,
const Quaternion& q) {
490 return Quaternion(q.r()*v.x() + v.y()*q.z() - v.z()*q.y(),
491 q.r()*v.y() + v.z()*q.x() - v.x()*q.z(),
492 q.r()*v.z() + v.x()*q.y() - v.y()*q.x(),
493 -q.x()*v.x() - v.y()*q.y() - v.z()*q.z());
498 operator* (
const Quaternion& q,
const double& d) {
499 return Quaternion( q.x()*d, q.y()*d, q.z()*d, q.r()*d );
504 operator* (
const double& d,
const Quaternion& q) {
505 return Quaternion( q.x()*d, q.y()*d, q.z()*d, q.r()*d );
510 operator+ (
const Quaternion& q1,
const Quaternion& q2) {
511 return Quaternion( q1.x()+q2.x(), q1.y()+q2.y(), q1.z()+q2.z(), q1.r()+q2.r() );
516 operator== (
const Quaternion& q1,
const Quaternion& q2) {
517 const double x = q1.x() - q2.x();
518 const double y = q1.y() - q2.y();
519 const double z = q1.z() - q2.z();
520 const double r = q1.r() - q2.r();
528 operator- (
const Quaternion& q1,
const Quaternion& q2) {
529 return Quaternion( q1.x()-q2.x(), q1.y()-q2.y(), q1.z()-q2.z(), q1.r()-q2.r() );
553 const double q0(
x());
554 const double q1(
y());
555 const double q2(
z());
556 const double real(
r());
557 x() = real*v.x() + q1*v.z() - q2*v.y();
558 y() = real*v.y() + q2*v.x() - q0*v.z();
559 z() = real*v.z() + q0*v.y() - q1*v.x();
560 r () = -v.x()*q0 - q1*v.y() - q2*v.z();
575 const double q0(
x());
576 const double q1(
y());
577 const double q2(
z());
578 const double real(
r());
579 x() = real*q.x() + q0*q.r() + q1*q.z() - q2*q.y();
580 y() = real*q.y() + q1*q.r() + q2*q.x() - q0*q.z();
581 z() = real*q.z() + q2*q.r() + q0*q.y() - q1*q.x();
582 r() = real*q.r() - q0*q.x() - q1*q.y() - q2*q.z();
612 return (
x()*
x() +
y()*
y() +
z()*
z() +
r()*
r());
618 return sqrt(
x()*
x() +
y()*
y() +
z()*
z() +
r()*
r());
624 const double norm = sqrt(
x()*
x() +
y()*
y() +
z()*
z() +
r()*
r());
636 const double norm = sqrt(
x()*
x() +
y()*
y() +
z()*
z() +
r()*
r());
647 return (fabs(
x()*
x() +
y()*
y() +
z()*
z()+
r()*
r())-1.0f) < 1.0e-8f;
653 const double q00 = 2.0 *
x() *
x();
654 const double q11 = 2.0 *
y() *
y();
655 const double q22 = 2.0 *
z() *
z();
656 const double q01 = 2.0 *
x() *
y();
657 const double q02 = 2.0 *
x() *
z();
658 const double q03 = 2.0 *
x() *
r();
659 const double q12 = 2.0 *
y() *
z();
660 const double q13 = 2.0 *
y() *
r();
661 const double q23 = 2.0 *
z() *
r();
663 v_out.x() = (1.0 - q11 - q22) * (v_in.x()) + (q01 - q23) * v_in.y() + (q02 + q13) * v_in.z();
664 v_out.y() = (q01 + q23) * v_in.x() + (1.0 - q22 - q00) * v_in.y() + (q12 - q03) * v_in.z();
665 v_out.z() = (q02 - q13) * v_in.x() + (q12 + q03) * v_in.y() + (1.0 - q11 - q00) * v_in.z();
671 const double q00 = 2.0 *
x() *
x();
672 const double q11 = 2.0 *
y() *
y();
673 const double q22 = 2.0 *
z() *
z();
674 const double q01 = 2.0 *
x() *
y();
675 const double q02 = 2.0 *
x() *
z();
676 const double q03 = -2.0 *
x() *
r();
677 const double q12 = 2.0 *
y() *
z();
678 const double q13 = -2.0 *
y() *
r();
679 const double q23 = -2.0 *
z() *
r();
681 v_out.x() = (1.0 - q11 - q22)*v_in.x() + (q01 - q23)*v_in.y() + (q02 + q13)*v_in.z();
682 v_out.y() = (q01 + q23)*v_in.x() + (1.0 - q22 - q00)*v_in.y() + (q12 - q03)*v_in.z();
683 v_out.z() = (q02 - q13)*v_in.x() + (q12 + q03)*v_in.y() + (1.0 - q11 - q00)*v_in.z();
689 const double q00 = 2.0 *
x() *
x();
690 const double q11 = 2.0 *
y() *
y();
691 const double q22 = 2.0 *
z() *
z();
692 const double q01 = 2.0 *
x() *
y();
693 const double q02 = 2.0 *
x() *
z();
694 const double q03 = 2.0 *
x() *
r();
695 const double q12 = 2.0 *
y() *
z();
696 const double q13 = 2.0 *
y() *
r();
697 const double q23 = 2.0 *
z() *
r();
699 return Vector ((1.0 - q11 - q22)*v_in.x() + (q01 - q23)*v_in.y() + (q02 + q13)*v_in.z(),
700 (q01 + q23)*v_in.x() + (1.0 - q22 - q00)*v_in.y() + (q12 - q03)*v_in.z(),
701 (q02 - q13)*v_in.x() + (q12 + q03)*v_in.y() + (1.0 - q11 - q00)*v_in.z());
708 const double q00 = 2.0 *
x() *
x();
709 const double q11 = 2.0 *
y() *
y();
710 const double q22 = 2.0 *
z() *
z();
711 const double q01 = 2.0 *
x() *
y();
712 const double q02 = 2.0 *
x() *
z();
713 const double q03 = -2.0 *
x() *
r();
714 const double q12 = 2.0 *
y() *
z();
715 const double q13 = -2.0 *
y() *
r();
716 const double q23 = -2.0 *
z() *
r();
718 return Vector ((1.0 - q11 - q22)*v_in.x() + (q01 - q23)*v_in.y() + (q02 + q13)*v_in.z(),
719 (q01 + q23)*v_in.x() + (1.0 - q22 - q00)*v_in.y() + (q12 - q03)*v_in.z(),
720 (q02 - q13)*v_in.x() + (q12 + q03)*v_in.y() + (1.0 - q11 - q00)*v_in.z());
757 return Vector(
x(),
y(),
z());
771 : coord(v.
x(), v.y(), v.
z(), 0.) {
#define SafeModeAssert(condition, message)
Definition: Macro.hpp:47
Definition: EulerAngle.hpp:61
Definition: Quaternion.hpp:54
void operator*=(const Quaternion &Q)
void get_axis_angle(Vector &axis, double &angle) const
Definition: Quaternion.cpp:131
friend std::ostream & operator<<(std::ostream &, const Quaternion &)
void set_y(const double &)
friend Quaternion operator+(const Quaternion &, const Quaternion &)
Tensor to_rotation_matrix() const
Definition: Quaternion.cpp:137
static Quaternion & glob(const std::string &id)
Definition: Quaternion.cpp:45
Eigen::Matrix< double, 4, 1 > coord
Definition: Quaternion.hpp:175
static std::string class_ID()
Definition: Quaternion.hpp:70
friend Quaternion operator*(const Quaternion &, const Vector &)
void operator+=(const Quaternion &Q)
double & operator()(unsigned int i)
void operator*=(const Vector &v)
double get_angle() const
Definition: Quaternion.cpp:115
Quaternion(const Vector &axis, double angle)
void set_vec_from_to(const Vector &from, const Vector &to)
void set_z(const double &)
Vector inverse_rotate(const Vector &v_in) const
friend Quaternion slerp(const Quaternion &, const Quaternion &, const double &ratio)
void set_r(const double &)
std::string info() const
Definition: Quaternion.cpp:176
EulerAngle to_euler_angle() const
Definition: Quaternion.cpp:94
Quaternion normalized() const
friend Quaternion operator-(const Quaternion &, const Quaternion &)
void operator*=(const double &d)
Quaternion(double vx, double vy, double vz, double s)
void add_glob(const std::string &id)
Definition: Quaternion.cpp:183
const double & operator()(unsigned int i) const
friend bool operator==(const Quaternion &, const Quaternion &)
Quaternion & operator=(const EulerAngle &)
Definition: Quaternion.cpp:102
Quaternion(const Vector &v)
void operator-=(const Quaternion &Q)
const double & val() const
void inverse_rotate(const Vector &v_in, Vector &v_out) const
void equalize(const Quaternion &)
static const int N
Definition: Quaternion.hpp:74
void set_axis_angle(const Vector &axis, double angle)
void serialize(Archive &ar, const unsigned int)
Quaternion conjugate() const
Vector get_axis() const
Definition: Quaternion.cpp:110
friend class boost::serialization::access
Definition: Quaternion.hpp:171
Quaternion(const Vector &from, const Vector &to)
double squared_norm() const
void set_value(double q0, double q1, double q2, double q3)
static const Quaternion & global
Definition: Quaternion.hpp:72
void set_angle(double angle)
Vector rotate(const Vector &v_in) const
static Quaternion * new_object(const TiXmlElement *el)
Definition: Quaternion.cpp:156
void rotate(const Vector &v_in, Vector &v_out) const
void set_x(const double &)
Quaternion(const Quaternion &q)
Quaternion & operator=(const Quaternion &Q)
Definition: Tensor.hpp:62
Definition: Vector.hpp:75
SymTensor operator+(const SymTensor &m1, const SymTensor &m2)
SymTensor operator-(const SymTensor &m1, const SymTensor &m2)
std::ostream & operator<<(std::ostream &, const EulerAngle &)
Vector operator*(const SymTensor &m, const Vector &v)
bool operator==(const EulerAngle &, const EulerAngle &)
Definition: Common.hpp:198
T pow(const T v0, const T v1)
Definition: Exprtk.hpp:1491
x y * z
Definition: Exprtk.hpp:11139
x y t t *t x y t t t x y t t t x *y t *t t x *y t *t t x y t t t x y t t t x(y+z)
Definition: Constant.hpp:48
static double epsilon
Definition: Constant.hpp:58