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