Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_MATH_MATH_ROTATION_H
00002 #define OPENTISSUE_CORE_MATH_MATH_ROTATION_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_vector3.h>
00013 #include <OpenTissue/core/math/math_matrix3x3.h>
00014 #include <OpenTissue/core/math/math_quaternion.h>
00015 #include <OpenTissue/core/math/math_value_traits.h>
00016
00017 #include <cmath>
00018 #include <iosfwd>
00019
00020
00021 namespace OpenTissue
00022 {
00023
00024 namespace math
00025 {
00026
00027 template<
00028 typename value_type_
00029
00030 >
00031 class Rotation
00032 {
00033 protected:
00034
00035 typedef typename OpenTissue::math::ValueTraits<value_type_> value_traits_ ;
00036
00037 public:
00038
00039 typedef value_traits_ value_traits;
00040 typedef value_type_ value_type;
00041 typedef Matrix3x3<value_type> matrix3x3_type;
00042 typedef Vector3<value_type> vector3_type;
00043 typedef Quaternion<value_type> quaternion_type;
00044
00045 protected:
00046
00047 value_type m_angle;
00048 vector3_type m_axis;
00049
00050 public:
00051
00052 value_type & angle() { return m_angle; }
00053 value_type const & angle() const { return m_angle; }
00054
00055 vector3_type & axis() { return m_axis; }
00056 vector3_type const & axis() const { return m_axis; }
00057
00058 public:
00059
00060 Rotation()
00061 : m_angle(value_traits::zero())
00062 , m_axis(value_traits::zero(),value_traits::zero(),value_traits::one())
00063 {}
00064
00065 explicit Rotation(quaternion_type const & q) { *this = q; }
00066
00067 explicit Rotation(matrix3x3_type const & R) { *this = R; }
00068
00069 ~Rotation(){}
00070
00071 Rotation & operator=(Rotation const & R)
00072 {
00073 m_angle = R.m_angle;
00074 m_axis = R.m_axis;
00075 return (*this);
00076 }
00077
00078 Rotation & operator=(quaternion_type const & q)
00079 {
00080 using std::acos;
00081 using std::sin;
00082
00083 value_type teta = boost::numeric_cast<value_type>( acos( q.s() ) );
00084 value_type sin_teta = boost::numeric_cast<value_type>( sin(teta) );
00085 m_angle = value_traits::two()*teta;
00086 if(sin_teta)
00087 m_axis = unit( q.v() / sin_teta );
00088 else
00089 m_axis = vector3_type(value_traits::zero(),value_traits::zero(),value_traits::one());
00090 return *this;
00091 }
00092
00093 Rotation & operator=(matrix3x3_type const & M)
00094 {
00095 Quaternion<value_type> tmp(M);
00096 (*this) = tmp;
00097 return *this;
00098 }
00099
00100 };
00101
00102 template<typename T>
00103 inline std::ostream & operator<< (std::ostream & o, Rotation<T> const & r)
00104 {
00105 o << "[" << r.angle() << "," << r.axis()(0) << "," << r.axis()(1) << "," << r.axis()(2) << "]";
00106 return o;
00107 }
00108
00109 template<typename T>
00110 inline std::istream & operator>>(std::istream & i, Rotation<T> & r)
00111 {
00112 char dummy;
00113 i >> dummy;
00114 i >> r.angle();
00115 i >> dummy;
00116 i >> r.axis()(0);
00117 i >> dummy;
00118 i >> r.axis()(1);
00119 i >> dummy;
00120 i >> r.axis()(2);
00121 i >> dummy;
00122 return i;
00123 }
00124
00125 }
00126
00127 }
00128
00129
00130 #endif