Go to the documentation of this file.00001 #ifndef OPENTISSUE_UTILITY_TRACKBALL_CHEN_H
00002 #define OPENTISSUE_UTILITY_TRACKBALL_CHEN_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/trackball/trackball_generic.h>
00013 #include <OpenTissue/core/math/math_constants.h>
00014
00015 namespace OpenTissue
00016 {
00017 namespace utility
00018 {
00019 namespace trackball
00020 {
00021
00022 template<typename real_type_ = double>
00023 class Chen : public GenericTrackball<real_type_>
00024 {
00025 public:
00026
00027 typedef GenericTrackball<real_type_> base_type;
00028 typedef typename base_type::real_type real_type;
00029 typedef typename base_type::vector3_type vector3_type;
00030 typedef typename base_type::matrix3x3_type matrix3x3_type;
00031 typedef typename base_type::quaternion_type quaternion_type;
00032 typedef typename base_type::gl_transform_type gl_transform_type;
00033
00034 public:
00035
00036 Chen()
00037 : base_type()
00038 {
00039 reset();
00040 }
00041
00042 Chen(real_type const & radius)
00043 : base_type(radius)
00044 {
00045 reset();
00046 }
00047
00048 void reset() { base_type::reset(); }
00049
00050 void begin_drag(real_type const & x, real_type const & y)
00051 {
00052 this->m_xform_anchor = this->m_xform_current;
00053 this->m_xform_incremental = diag(1.0);
00054 this->m_xform_current = diag(1.0);
00055 this->m_anchor_position = vector3_type(x,y,0);
00056 this->m_current_position = vector3_type(x,y,0);
00057 }
00058
00059 void drag(real_type const & x, real_type const & y)
00060 {
00061 this->m_current_position = vector3_type(x, y, 0);
00062 compute_incremental(this->m_anchor_position,this->m_current_position,this->m_xform_incremental);
00063 }
00064
00065 void end_drag(real_type const & x, real_type const & y)
00066 {
00067 this->m_current_position = vector3_type(x, y, 0);
00068 compute_incremental(this->m_anchor_position,this->m_current_position,this->m_xform_incremental);
00069 }
00070
00071 private:
00072
00073 real_type f(real_type const & x) const
00074 {
00075 if (x <= 0) return 0;
00076 if (x >= 1) return math::detail::pi_2<real_type>();
00077 return math::detail::pi_2<real_type>() * x;
00078 }
00079
00080 void compute_incremental(vector3_type const & anchor, vector3_type const & current, matrix3x3_type & transform)
00081 {
00082 using std::cos;
00083 using std::sin;
00084 using std::fabs;
00085 real_type length_anchor = length(anchor);
00086 vector3_type Pa = unit(anchor);
00087 vector3_type Pc = unit(current);
00088 vector3_type aXc = Pa % Pc;
00089 real_type tau = atan2(length(aXc), Pa * Pc );
00090 real_type phi = atan2(anchor(1), anchor(0));
00091 real_type omega = f(length_anchor / this->m_radius);
00092 this->m_axis = unit(
00093 vector3_type(
00094 -cos(tau) * sin(phi) - cos(omega) * cos(phi) * sin(tau)
00095 , cos(phi) * cos(tau) - cos(omega) * sin(phi) * sin(tau)
00096 , sin(omega) * sin(tau)
00097 )
00098 );
00099
00100 vector3_type d = current - anchor;
00101 this->m_angle = math::detail::pi_2<real_type>() * length(d) / this->m_radius * (1 - (1 - 0.2 / math::detail::pi<real_type>()) * 2 * omega / math::detail::pi<real_type>() *(1 - fabs(cos(tau))));
00102 transform = Ru(this->m_angle,this->m_axis);
00103 }
00104 };
00105 }
00106 }
00107 }
00108
00109
00110 #endif