last-svn-commit-514-gbddf6ea mln/fun/x2x/rotation.hh: Aesthetic changes.

--- milena/ChangeLog | 4 + milena/mln/fun/x2x/rotation.hh | 211 ++++++++++++++++++++-------------------- 2 files changed, 110 insertions(+), 105 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index e5fef24..9ed9189 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,5 +1,9 @@ 2010-10-21 Roland Levillain <roland@lrde.epita.fr> + * mln/fun/x2x/rotation.hh: Aesthetic changes. + +2010-10-21 Roland Levillain <roland@lrde.epita.fr> + Ensure non implemented rotation code stops the execution. * mln/fun/x2x/rotation.hh diff --git a/milena/mln/fun/x2x/rotation.hh b/milena/mln/fun/x2x/rotation.hh index d9e5940..3cd54f1 100644 --- a/milena/mln/fun/x2x/rotation.hh +++ b/milena/mln/fun/x2x/rotation.hh @@ -61,80 +61,83 @@ namespace mln namespace internal { - template < unsigned n, typename C > - algebra::h_mat<n, C> - get_rot_h_mat(const C alpha_, const algebra::vec<n,C>& axis_) - { + // (Axis, angle)-based rotation: general case (not implemented). + template < unsigned n, typename C > + algebra::h_mat<n, C> + get_rot_h_mat(const C alpha_, const algebra::vec<n,C>& axis_) + { std::cerr << __FILE__ << ":" << __LINE__ << ": error:" << " generic mln::fun::x2x::internal::get_rot_h_mat<n, C>" << " not implemented." << std::endl; std::abort(); - } - - template <typename C > - algebra::h_mat<3, C> - get_rot_h_mat(const C alpha_, const algebra::vec<3,C>& axis_) - { - //test axis is valid + } + + // (Axis, angle)-based rotation: 2D case. + template <typename C > + algebra::h_mat<2, C> + get_rot_h_mat(const C alpha, const algebra::vec<2,C>&) + { + const C cos_a = cos(alpha); + const C sin_a = sin(alpha); + + algebra::h_mat<2, C> m; + + m(0,0) = cos_a; m(0,1) = -sin_a; m(0,2) = 0; + m(1,0) = sin_a; m(1,1) = cos_a; m(1,2) = 0; + m(2,0) = 0; m(2,1) = 0; m(2,2) = 1; + + return m; + } + + // (Axis, angle)-based rotation: 3D case. + template <typename C > + algebra::h_mat<3, C> + get_rot_h_mat(const C alpha, const algebra::vec<3,C>& axis) + { + // Ensure axis is valid. typedef algebra::vec<3,C> vec_t; - //FIXME: cannot use '!=' operator. - mln_precondition(!(axis_ == vec_t(literal::zero))); - - /// Be sure that axis is normalized. - algebra::vec<3,C> axis = axis_; - axis.normalize(); - - const C cos_a = cos(alpha_); - const C sin_a = sin(alpha_); - const C u = axis_[0]; - const C v = axis_[1]; - const C w = axis_[2]; - const C u2 = u * u; - const C v2 = v * v; - const C w2 = w * w; - - algebra::h_mat<3, C> m_; - - m_(0,0) = u2 + (1 - u2) * cos_a; - m_(0,1) = u*v * (1 - cos_a) - w * sin_a; - m_(0,2) = u*w * (1 - cos_a) + v * sin_a; - m_(0,3) = 0; - - m_(1,0) = u*v * (1 - cos_a) + w * sin_a; - m_(1,1) = v2 + (1 - v2) * cos_a; - m_(1,2) = v * w * (1 - cos_a) - u * sin_a; - m_(1,3) = 0; - - m_(2,0) = u * w * (1 - cos_a) - v * sin_a; - m_(2,1) = v * w * (1 - cos_a) + u * sin_a; - m_(2,2) = w2 + (1 - w2) * cos_a; - m_(2,3) = 0; - - m_(3,0) = 0; - m_(3,1) = 0; - m_(3,2) = 0; - m_(3,3) = 1; - - return m_; - } - - template <typename C > - algebra::h_mat<2, C> - get_rot_h_mat(const C alpha_, const algebra::vec<2,C>&) - { - const C cos_a = cos(alpha_); - const C sin_a = sin(alpha_); - - algebra::h_mat<2, C> m_; - - m_(0,0) = cos_a; m_(0,1) = -sin_a; m_(0,2) = 0; - m_(1,0) = sin_a; m_(1,1) = cos_a; m_(1,2) = 0; - m_(2,0) = 0; m_(2,1) = 0; m_(2,2) = 1; - - return m_; - } + // FIXME: This check is not precise enought when the vector + // holds floating point values. + mln_precondition(axis != vec_t(literal::zero)); + + algebra::vec<3,C> normed_axis = axis; + normed_axis.normalize(); + + const C cos_a = cos(alpha); + const C sin_a = sin(alpha); + const C u = normed_axis[0]; + const C v = normed_axis[1]; + const C w = normed_axis[2]; + const C u2 = u * u; + const C v2 = v * v; + const C w2 = w * w; + + algebra::h_mat<3, C> m; + + m(0,0) = u2 + (1 - u2) * cos_a; + m(0,1) = u * v * (1 - cos_a) - w * sin_a; + m(0,2) = u * w * (1 - cos_a) + v * sin_a; + m(0,3) = 0; + + m(1,0) = u * v * (1 - cos_a) + w * sin_a; + m(1,1) = v2 + (1 - v2) * cos_a; + m(1,2) = v * w * (1 - cos_a) - u * sin_a; + m(1,3) = 0; + + m(2,0) = u * w * (1 - cos_a) - v * sin_a; + m(2,1) = v * w * (1 - cos_a) + u * sin_a; + m(2,2) = w2 + (1 - w2) * cos_a; + m(2,3) = 0; + + m(3,0) = 0; + m(3,1) = 0; + m(3,2) = 0; + m(3,3) = 1; + + return m; + } } // end of namespace internal @@ -142,44 +145,43 @@ namespace mln /// Represent a rotation function. template <unsigned n, typename C> struct rotation - : - fun::internal::x2x_linear_impl_< algebra::vec<n,C>, C, rotation<n,C> > - , - public Function_v2v< rotation<n,C> > + : fun::internal::x2x_linear_impl_< algebra::vec<n,C>, C, rotation<n,C> >, + public Function_v2v< rotation<n,C> > { /// Type of the underlying data stored in vectors and matrices. typedef C data_t; /// Type of the inverse function. typedef rotation<n,C> invert; - /// Return the invere function. + /// Return the inverse function. invert inv() const; /// Constructor without argument. - rotation(); - /// Constructor with radian alpha and a facultative direction (rotation axis). - rotation(C alpha, const algebra::vec<n,C>& axis); - /// Constructor with quaternion - rotation(const algebra::quat& q); + rotation(); + /// Constructor with radian alpha and a facultative direction + /// (rotation axis). + rotation(C alpha, const algebra::vec<n,C>& axis); + /// Constructor with quaternion + rotation(const algebra::quat& q); /// Constructor with h_mat. - rotation(const algebra::h_mat<n,C>& m); + rotation(const algebra::h_mat<n,C>& m); /// Perform the rotation of the given vector. - algebra::vec<n,C> operator()(const algebra::vec<n,C>& v) const; + algebra::vec<n,C> operator()(const algebra::vec<n,C>& v) const; /// Set a new grade alpha. - void set_alpha(C alpha); + void set_alpha(C alpha); /// Set a new rotation axis. - void set_axis(const algebra::vec<n,C>& axis); + void set_axis(const algebra::vec<n,C>& axis); protected: - void update(); + void update(); bool check_rotation(const algebra::quat& q); - - /// FIXME: Is it useful? - C alpha_; - algebra::vec<n,C> axis_; + /* FIXME: Is it useful to keep these values, since they are + primarily used to build the matrix `m_'? */ + C alpha_; + algebra::vec<n,C> axis_; }; @@ -194,8 +196,8 @@ namespace mln template <unsigned n, typename C> inline rotation<n,C>::rotation(C alpha, const algebra::vec<n,C>& axis) - :alpha_(alpha), - axis_(axis) + : alpha_(alpha), + axis_(axis) { this->m_ = algebra::h_mat<n,C>::Id; update(); @@ -205,25 +207,24 @@ namespace mln inline rotation<n,C>::rotation(const algebra::quat& q) { - // FIXME: Should also work for 2d. - mlc_bool(n == 3)::check(); - mln_precondition(q.is_unit()); + // FIXME: Should also work for 2D. + mlc_bool(n == 3)::check(); + mln_precondition(q.is_unit()); - C - w = q.to_vec()[0], - x = q.to_vec()[1], x2 = 2*x*x, xw = 2*x*w, - y = q.to_vec()[2], y2 = 2*y*y, xy = 2*x*y, yw = 2*y*w, - z = q.to_vec()[3], z2 = 2*z*z, xz = 2*x*z, yz = 2*y*z, zw = 2*z*w; + C + w = q.to_vec()[0], + x = q.to_vec()[1], x2 = 2*x*x, xw = 2*x*w, + y = q.to_vec()[2], y2 = 2*y*y, xy = 2*x*y, yw = 2*y*w, + z = q.to_vec()[3], z2 = 2*z*z, xz = 2*x*z, yz = 2*y*z, zw = 2*z*w; - C t[9] = {1.f - y2 - z2, xy - zw, xz + yw, - xy + zw, 1.f - x2 - z2, yz - xw, - xz - yw, yz + xw, 1.f - x2 - y2}; + C t[9] = {1.f - y2 - z2, xy - zw, xz + yw, + xy + zw, 1.f - x2 - z2, yz - xw, + xz - yw, yz + xw, 1.f - x2 - y2}; - this->m_ = mln::make::h_mat(t); + this->m_ = mln::make::h_mat(t); mln_assertion(check_rotation(q)); - /// Update attributes - + /// Update attributes. alpha_ = acos(w) * 2; axis_[0] = x; axis_[1] = y; @@ -281,18 +282,18 @@ namespace mln void rotation<n,C>::set_axis(const algebra::vec<n,C>& axis) { - axis_ = axis; + axis_ = axis; update(); } // Homogenous matrix for a rotation of a point (x,y,z) - // about the vector (u,v,w) by the angle alpha + // about the vector (u,v,w) by the angle alpha. template <unsigned n, typename C> inline void rotation<n,C>::update() { - this->m_ = internal::get_rot_h_mat(alpha_, axis_); + this->m_ = internal::get_rot_h_mat(alpha_, axis_); } template <unsigned n, typename C> -- 1.5.6.5
participants (1)
-
Roland Levillain