
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-09-24 Simon Nivault <simon.nivault@lrde.epita.fr> Add rotation and fix for translation. * mln/fun/x2x/rotation.hh: New. * mln/fun/x2x/translation.hh: Fix. * mln/metal/mat.hh: Fix, declarations. * tests/fun_x2x_rotation.cc: New. * tests/fun_x2x_translation.cc: Fix. --- mln/fun/x2x/rotation.hh | 170 +++++++++++++++++++++++++++++++++++++++++++ mln/fun/x2x/translation.hh | 4 - mln/metal/mat.hh | 79 +++++++++++++++++++ tests/fun_x2x_rotation.cc | 68 +++++++++++++++++ tests/fun_x2x_translation.cc | 1 5 files changed, 319 insertions(+), 3 deletions(-) Index: trunk/milena/tests/fun_x2x_translation.cc =================================================================== --- trunk/milena/tests/fun_x2x_translation.cc (revision 1162) +++ trunk/milena/tests/fun_x2x_translation.cc (revision 1163) @@ -50,4 +50,5 @@ std::cout << vec1 << std::endl; std::cout << tr1(vec1) << std::endl; + std::cout << tr1.inv()(vec1) << std::endl; } Index: trunk/milena/tests/fun_x2x_rotation.cc =================================================================== --- trunk/milena/tests/fun_x2x_rotation.cc (revision 0) +++ trunk/milena/tests/fun_x2x_rotation.cc (revision 1163) @@ -0,0 +1,68 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +/*! \file tests/image2d_b.cc + * + * \brief Tests on mln::image2d_b. + */ + + +#include <iostream> +#include <mln/fun/x2x/rotation.hh> +#include <mln/core/image2d_b.hh> +#include <mln/value/int_u8.hh> +#include <mln/io/pgm/load.hh> +#include <mln/io/pgm/save.hh> +#include <mln/core/interpolated.hh> + + +int main() +{ + using namespace mln; + using value::int_u8; + + image2d_b<int_u8> lena = io::pgm::load("../img/lena.pgm"); + image2d_b<int_u8> out(lena.domain()); + + const float row = (float)(geom::max_row(lena) - geom::min_row(lena)) / 2; + const float col = (float)(geom::max_col(lena) - geom::min_col(lena)) / 2; + interpolated<image2d_b<int_u8> > inter(lena); + + fun::x2x::rotation<2,float> rot1(3.1416, make::vec(row,col)); + + image2d_b<int_u8>::fwd_piter p(out.domain()); + + for_all(p) + { + metal::vec<2,float> v = rot1.inv()((point2d::vec_t)(point2d)p); + if (inter.owns_(v)) + out(p) = inter(v); + else + out(p) = 255; + } + io::pgm::save(out, "out.pgm"); +} Index: trunk/milena/mln/fun/x2x/translation.hh =================================================================== --- trunk/milena/mln/fun/x2x/translation.hh (revision 1162) +++ trunk/milena/mln/fun/x2x/translation.hh (revision 1163) @@ -56,7 +56,7 @@ enum {dim = n}; typedef metal::vec<n,C> result; - typedef metal::vec<n,C> invert; + typedef translation<n,C> invert; translation(); translation(const metal::vec<n,C>& t); @@ -102,7 +102,7 @@ } template <unsigned n, typename C> - metal::vec<n,C> + translation<n,C> translation<n,C>::inv() const { typename translation::invert res(-t_); Index: trunk/milena/mln/fun/x2x/rotation.hh =================================================================== --- trunk/milena/mln/fun/x2x/rotation.hh (revision 0) +++ trunk/milena/mln/fun/x2x/rotation.hh (revision 1163) @@ -0,0 +1,170 @@ +// Copyright (C) 2007 EPITA Research and Development Laboratory +// +// This file is part of the Olena Library. This library is free +// software; you can redistribute it and/or modify it under the terms +// of the GNU General Public License version 2 as published by the +// Free Software Foundation. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02111-1307, USA. +// +// As a special exception, you may use this file as part of a free +// software library without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to +// produce an executable, this file does not by itself cause the +// resulting executable to be covered by the GNU General Public +// License. This exception does not however invalidate any other +// reasons why the executable file might be covered by the GNU General +// Public License. + +#ifndef MLN_FUN_X2X_ROTATION_HH +# define MLN_FUN_X2X_ROTATION_HH + +/*! \file mln/fun/x2x/rotation.hh + * + * \brief FIXME. + */ + +# include <mln/core/concept/function.hh> +# include <mln/metal/vec.hh> +# include <mln/metal/mat.hh> +# include <cmath> + + +namespace mln +{ + + namespace fun + { + + namespace x2x + { + + // FIXME: Doc! + + template <unsigned n, typename C> + struct rotation : public Function_x2x< rotation<n,C> > + { + + enum {dim = n}; + + typedef metal::vec<n,C> result; + typedef rotation<n,C> invert; + + rotation(); + rotation(const float alpha, const metal::vec<n,C>& t); + + result operator()(const metal::vec<n,C>& v) const; + invert inv() const; + + void set_t(const metal::vec<n,C>& t); + void set_alpha(const float alpha); + + protected: + + float alpha_; + metal::vec<n,C> t_; + metal::mat<n + 1,n + 1,C> m_; + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned n, typename C> + rotation<n,C>::rotation() + { + t_ = make::vec<n,C>(0); + m_ = metal::mat<n+1,n+1,C>::Id; + } + + template <unsigned n, typename C> + rotation<n,C>::rotation(const float alpha, const metal::vec<n,C>& t) + :alpha_(alpha), + t_(t) + { + const float cos_a = cos(alpha_); + const float sin_a = sin(alpha_); + const float c_1 = 1 - cos_a; + const float coord1 = c_1 * t[0] + sin_a * t[1]; + const float coord2 = t[1] * c_1 - sin_a * t[0]; + + m_ = metal::mat<n+1,n+1,C>::Id; + m_(0,2) = coord1; + m_(1,2) = coord2; + m_(0,0) = cos_a; + m_(0,1) = -sin_a; + m_(1,0) = sin_a; + m_(1,1) = cos_a; + } + + template <unsigned n, typename C> + metal::vec<n,C> + rotation<n,C>::operator()(const metal::vec<n,C>& v) const + { + metal::mat<n+1,1,C> hmg; + metal::mat<n+1,1,C> tmp; + metal::vec<n,C> res; + + for (unsigned i = 0; i < n; ++i) + hmg(i,0) = v[i]; + hmg(n,0) = 1; + tmp = m_ * hmg; + mln_assertion(tmp(n,0) == 1); + for (unsigned i = 0; i < n; ++i) + res[i] = tmp(i,0); + return res; + } + + template <unsigned n, typename C> + rotation<n,C> + rotation<n,C>::inv() const + { + typename rotation::invert res(-alpha_, t_); + + return res; + } + + template <unsigned n, typename C> + void + rotation<n,C>::set_t(const metal::vec<n,C>& t) + { + t_ = t; + for (unsigned i = 0; i < n; ++i) + m_(i,n) = t_[i]; + } + + template <unsigned n, typename C> + void + rotation<n,C>::set_alpha(const float alpha) + { + const float cos_a = cos(alpha); + const float sin_a = sin(alpha); + + alpha_ = alpha; + + m_(0,0) = cos_a; + m_(0,1) = -sin_a; + m_(1,0) = sin_a; + m_(1,1) = cos_a; + } + + + +# endif // ! MLN_INCLUDE_ONLY + + } // end of namespace mln::fun::x2x + + } // end of namespace mln::fun + +} // end of namespace mln + + +#endif // ! MLN_FUN_X2X_ROTATION_HH Index: trunk/milena/mln/metal/mat.hh =================================================================== --- trunk/milena/mln/metal/mat.hh (revision 1162) +++ trunk/milena/mln/metal/mat.hh (revision 1163) @@ -74,6 +74,83 @@ T data_[n][m]; }; + // eq + + template <unsigned n, unsigned m, typename T, typename U> + bool + operator==(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs); + + template <unsigned n, unsigned m, typename T, typename U> + bool + operator!=(const mat<n,m,T>& lhs, const mat<n,m,U>& rhs); + + // + + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T>& + operator+=(mat<n,m,T>& lhs, const mat<n,m,U>& rhs); + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator+(mat<n,m,T>& lhs, const mat<n,m,U>& rhs); + + // - + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T>& + operator-=(mat<n,m,T>& lhs, const mat<n,m,U>& rhs); + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator-(mat<n,m,T>& lhs, const mat<n,m,U>& rhs); + + template <unsigned n, unsigned m, typename T> + mat<n,m,T> + operator-(const mat<n,m,T>& lhs); + + // * + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T>& + operator*=(mat<n,m,T>& lhs, const U& scalar); + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator*(mat<n,m,T>& lhs, const U& scalar); + + template <unsigned n, unsigned m, unsigned o, typename T, typename U> + mat<n,m,T>& + operator*=(mat<n,o,T>& lhs, mat<o,m,U>& rhs); + + template <unsigned n, unsigned m, unsigned o, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs); + + // / + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,T> + operator/=(mat<n,m,T>& lhs, const U& scalar); + + template <unsigned n, unsigned m, typename T, typename U> + mat<n,m,typename binary_arith_trait<T,U>::ret> + operator/(mat<n,m,T>& lhs, const U& scalar); + + // << + + template <unsigned n, unsigned m, typename T> + std::ostream& + operator<<(std::ostream& ostr, const mat<n,m,T>& v); + + template <unsigned n, unsigned m> + std::ostream& + operator<<(std::ostream& ostr, const mat<n,m,unsigned char>& v); + + template <unsigned n, unsigned m> + std::ostream& + operator<<(std::ostream& ostr, const mat<n,m,signed char>& v); + + # ifndef MLN_INCLUDE_ONLY template <unsigned n, unsigned m, typename T> @@ -246,7 +323,7 @@ } template <unsigned n, unsigned m, unsigned o, typename T, typename U> mat<n,m,typename binary_arith_trait<T,U>::ret> - operator*(mat<n,o,T>& lhs, mat<o,m,U>& rhs) + operator*(const mat<n,o,T>& lhs, const mat<o,m,U>& rhs) { mat<n,m,typename binary_arith_trait<T,U>::ret> tmp; for (unsigned i = 0; i < n; ++i)