milena r1303: Update transformations

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2007-10-10 Simon Nivault <simon.nivault@lrde.epita.fr> Update transformations. * mln/core/concept/function.hh: Add bijective concept. * mln/core/h_mat.hh: Add homogen matrix. * mln/fun/internal/x2x_impl.hh, * mln/fun/x2x/composed.hh, * mln/fun/x2x/rotation.hh, * mln/fun/x2x/translation.hh, * mln/make/vec.hh, * tests/fun_x2x_translation.cc: Update. --- mln/core/concept/function.hh | 24 +++++++++++ mln/core/h_mat.hh | 73 +++++++++++++++++++++++++++++++++ mln/fun/internal/x2x_impl.hh | 16 ++++++- mln/fun/x2x/composed.hh | 93 +++++++++++++++++++++---------------------- mln/fun/x2x/rotation.hh | 40 ++++++++---------- mln/fun/x2x/translation.hh | 49 ++++++++++++---------- mln/make/vec.hh | 38 +++++++++++++---- tests/fun_x2x_translation.cc | 3 - 8 files changed, 234 insertions(+), 102 deletions(-) Index: trunk/milena/tests/fun_x2x_translation.cc =================================================================== --- trunk/milena/tests/fun_x2x_translation.cc (revision 1302) +++ trunk/milena/tests/fun_x2x_translation.cc (revision 1303) @@ -33,6 +33,7 @@ #include <iostream> #include <mln/fun/x2x/translation.hh> +#include <mln/fun/i2v/all.hh> @@ -46,7 +47,7 @@ c = 2.9; metal::vec<3,float> vec1 = make::vec(a, b, c); - fun::x2x::translation<3,float> tr1(make::vec<3,float>(1.6)); + fun::x2x::translation<3,float> tr1(make::vec<3, float>(all(1.6))); std::cout << vec1 << std::endl; std::cout << tr1(vec1) << std::endl; Index: trunk/milena/mln/core/h_mat.hh =================================================================== --- trunk/milena/mln/core/h_mat.hh (revision 0) +++ trunk/milena/mln/core/h_mat.hh (revision 1303) @@ -0,0 +1,73 @@ +// 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_CORE_H_MAT_HH +# define MLN_CORE_H_MAT_HH + +/*! \file mln/core/h_mat.hh + * + * \brief Definition of the mln::h_mat alias and of its + * construction routine. + */ + +# include <mln/metal/mat.hh> + + +namespace mln +{ + + + template <unsigned dim, typename T> + struct h_mat : public metal::mat<dim+1, dim+1, T> + { + h_mat(); + + h_mat(const metal::mat<dim+1, dim+1, T>& x); + }; + + +# ifndef MLN_INCLUDE_ONLY + + template <unsigned dim, typename T> + h_mat<dim,T>::h_mat() + : metal::mat<dim+1, dim+1, T>(metal::mat<dim+1, dim+1, T>::Id) + { + } + + template <unsigned dim, typename T> + h_mat<dim,T>::h_mat(const metal::mat<dim+1, dim+1, T>& x) + : metal::mat<dim+1, dim+1, T>(x) + { + } + +# endif // ! MLN_INCLUDE_ONLY + +} // end of namespace mln + + + +#endif // ! MLN_CORE_H_MAT_HH Index: trunk/milena/mln/core/concept/function.hh =================================================================== --- trunk/milena/mln/core/concept/function.hh (revision 1302) +++ trunk/milena/mln/core/concept/function.hh (revision 1303) @@ -162,6 +162,22 @@ Function_x2x(const Function_x2x&); }; + // Vector <-> Vector. + + /// Base class for implementation of bijective function-objects from + /// vector to vector. + template <typename E> + struct Bijection_x2x : public Function_x2x< E > + { + /* + typedef invert; + invert inv() const; + */ + protected: + Bijection_x2x(); + }; + + # ifndef MLN_INCLUDE_ONLY @@ -256,6 +272,14 @@ { } + template <typename E> + Bijection_x2x<E>::Bijection_x2x() + { + typedef typename E::invert invert; + invert (E::*m)() const = & E::inv; + m = 0; + } + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln Index: trunk/milena/mln/make/vec.hh =================================================================== --- trunk/milena/mln/make/vec.hh (revision 1302) +++ trunk/milena/mln/make/vec.hh (revision 1303) @@ -26,7 +26,7 @@ // Public License. #ifndef MLN_MAKE_VEC_HH -# define MLN_METAL_VEC_HH +# define MLN_MAKE_VEC_HH /*! \file mln/make/vec.hh * @@ -34,6 +34,7 @@ */ # include <mln/metal/vec.hh> +# include <mln/core/concept/function.hh> namespace mln { @@ -44,12 +45,21 @@ /*! \brief Create an mln::metal::vec<n,T>. * - * \param[in] v Value. + * \param[in] f Function. * - * \return A nD vector filled with \p v. + * \return A nD vector filled with the function \p f . */ - template <unsigned n, typename T> - metal::vec<n, T> vec(const T& v); + template <unsigned n, typename T, typename F> + metal::vec<n, T> vec(const Function_i2v<F>& f_); + + /*! \brief Create an mln::metal::vec<n,T>. + * + * \param[in] v_0 First coordinate. + * + * \return A 1D vector. + */ + template <typename T> + metal::vec<1, T> vec(const T& v_0); /*! \brief Create an mln::metal::vec<2,T>. * @@ -87,12 +97,22 @@ # ifndef MLN_INCLUDE_ONLY - template <unsigned n, typename T> - metal::vec<n, T> vec(const T& v) + template <unsigned n, typename T, typename F> + metal::vec<n, T> vec(const Function_i2v<F>& f_) { + mlc_converts_to(mln_result(F), T)::check(); + F f = exact(f_); metal::vec<n, T> tmp; - for (unsigned i = 0; i < n; ++i) - tmp[i] = v; + for (unsigned i; i < n; ++i) + tmp[i] = f(i); + return tmp; + } + + template <typename T> + metal::vec<1, T> vec(const T& v_0) + { + metal::vec<1, T> tmp; + tmp[0] = v_0; return tmp; } Index: trunk/milena/mln/fun/x2x/composed.hh =================================================================== --- trunk/milena/mln/fun/x2x/composed.hh (revision 1302) +++ trunk/milena/mln/fun/x2x/composed.hh (revision 1303) @@ -34,8 +34,9 @@ */ # include <mln/core/concept/function.hh> +# include <mln/fun/internal/x2x_impl.hh> # include <mln/metal/vec.hh> -# include <mln/metal/mat.hh> +# include <mln/core/h_mat.hh> namespace mln @@ -48,26 +49,26 @@ { // Fwd decl. - template <typename L, typename M> + template <typename F, typename G> struct composed; namespace internal { - template <unsigned n, typename L, unsigned m, typename M, typename E> + template <typename F, typename G, typename E> struct helper_; - template <unsigned n, typename L, typename M, typename E> - struct helper_<n, Function_x2x<L>, n, Function_x2x<M> > : Function_x2x<E> + template <typename F, typename G, typename E> + struct helper_<Function_x2x<F>, Function_x2x<G>, E> + : Function_x2x<E> { - enum {dim = n}; }; - template <unsigned n, typename L, typename M, typename E> - struct helper_<n, bijective_tr<L>, n, bijective_tr<M> > : bijective_tr<E> + template <typename F, typename G, typename E> + struct helper_<Bijection_x2x<F>, Bijection_x2x<G>, E > + : Bijection_x2x<E> { - enum {dim = n}; - typedef composed<M::invert,L::invert> invert; + typedef composed<G::invert,F::invert> invert; invert inv() const; }; @@ -75,78 +76,78 @@ // FIXME: Doc! - template <typename L, typename M> - struct composed : public internal::helper_< L::dim, L, M::dim, M, composed<L,M> > + template <typename F, typename G> + struct composed + : internal::x2x_impl_<F::result, composed<F,G> >, + public internal::helper_< F, G, composed<F,G> >, + private typename metal::bool<(F::dim == G::dim)>::check_t, + private typename metal::is<F::argument, G::result>::check_t { - typedef internal::helper_< L::dim, L, M::dim, M, composed<L,M> > Super - - enum {dim = Super::dim}; - - typedef metal::vec<n,C> result; + typedef internal::x2x_impl_<F::result, composed<F,G> > super_ composed(); - composed(const L& tr_l, const M& tr_m); + composed(const F& f, const G& g); - result operator()(const metal::vec<n,C>& v) const; + using super_:operator(); + metal::vec<super_::dim,C> operator()(const metal::vec<super_::dim,C>& v) const; - void set_first(const L& tr_l); - void set_second(const M& tr_m); + void set_first(const F& f); + void set_second(const G& g); protected: - L tr1_; - M tr2_; - metal::mat<n + 1,n + 1,C> m_; + F f_; + G g_; }; # ifndef MLN_INCLUDE_ONLY - template <typename L, typename M> - composed<L,M>::composed() + template <typename F, typename G> + composed<F,G>::composed() { - t_ = make::vec<n,C>(0); - m_ = metal::mat<n+1,n+1,C>::Id; + m_ = h_mat<n,C>::Id; } - template <typename L, typename M> - composed<L,M>::composed(const L& tr_l, const M& tr_m) - :tr1_(tr_l), - tr2_(tr_m) + template <typename F, typename G> + composed<F,G>::composed(const F& f, const G& g) + :f_(f), + g_(g) { - m_ = metal::mat<n+1,n+1,C>::Id; - m_ = tr1_ * tr2_; + m_ = f_.mat() * g_.mat(); } - template <typename L, typename M> - composed<L,M>::result - composed<L,M>::operator()(const metal::vec<n,C>& v) const + template <typename F, typename G> + metal::vec<super_::dim,C> + composed<F,G>::operator()(const metal::vec<super_::dim,C>& v) const { return m_(v); } - template <typename L, typename M> - composed<L,M>::invert - composed<L,M>::inv() const + template <typename F, typename G> + composed<F,G>::invert + composed<F,G>::inv() const { typename composed::invert res(tr2_.inv(), tr1_.inv()); return res; } - template <typename L, typename M> + template <typename F, typename G> void - composed<L,M>::set_first(const L& tr_l) + composed<F,G>::set_first(const F& f) { - tr1_ = tr_l; + f_ = f; + m_ = f_.mat() * g_.mat(); } - template <typename L, typename M> + template <typename F, typename G> void - composed<L,M>::set_second(const M& tr_m) + composed<F,G>::set_second(const G& g) { - tr2_ = tr_m; + g_ = g; + m_ = f_.mat() * g_.mat(); } # endif // ! MLN_INCLUDE_ONLY Index: trunk/milena/mln/fun/x2x/translation.hh =================================================================== --- trunk/milena/mln/fun/x2x/translation.hh (revision 1302) +++ trunk/milena/mln/fun/x2x/translation.hh (revision 1303) @@ -33,10 +33,11 @@ * \brief FIXME. */ -# include <mln/fun/x2x/bijective_tr.hh> +# include <mln/core/concept/function.hh> +# include <mln/fun/internal/x2x_impl.hh> # include <mln/metal/vec.hh> -# include <mln/metal/mat.hh> - +# include <mln/core/h_mat.hh> +# include <mln/fun/i2v/all.hh> namespace mln { @@ -50,26 +51,27 @@ // FIXME: Doc! template <unsigned n, typename C> - struct translation : public bijective_tr< translation<n,C> > + struct translation + : internal::x2x_impl_< metal::vec<n,C>, translation<n,C> > + , public Bijection_x2x< translation<n,C> > { + typedef fun::internal::x2x_impl_< metal::vec<n,C>, translation<n,C> > super_; - enum {dim = n}; - - typedef metal::vec<n,C> result; typedef translation<n,C> invert; + invert inv() const; translation(); translation(const metal::vec<n,C>& t); - result operator()(const metal::vec<n,C>& v) const; - invert inv() const; + using super_::operator(); + metal::vec<n,C> operator()(const metal::vec<n,C>& v) const; void set_t(const metal::vec<n,C>& t); protected: + void update(); metal::vec<n,C> t_; - metal::mat<n + 1,n + 1,C> m_; }; @@ -78,28 +80,23 @@ template <unsigned n, typename C> translation<n,C>::translation() { - t_ = make::vec<n,C>(0); - m_ = metal::mat<n+1,n+1,C>::Id; + t_ = make::vec<n,C>(fun::i2v::all<C>(0)); + this->m_ = h_mat<n,C>::Id; } template <unsigned n, typename C> translation<n,C>::translation(const metal::vec<n,C>& t) :t_(t) { - m_ = metal::mat<n+1,n+1,C>::Id; - for (unsigned i = 0; i < n; ++i) - m_(i,n) = t_[i]; + this->m_ = h_mat<n,C>::Id; + this->update(); } template <unsigned n, typename C> metal::vec<n,C> translation<n,C>::operator()(const metal::vec<n,C>& v) const { - typename translation::result res; - // FIXME: Why not "res = v + t_;"? - for (unsigned i = 0; i < n; ++i) - res[i] = v[i] + t_[i]; - return res; + return v + t_; } template <unsigned n, typename C> @@ -115,11 +112,17 @@ void translation<n,C>::set_t(const metal::vec<n,C>& t) { - t_ = t; - for (unsigned i = 0; i < n; ++i) - m_(i,n) = t_[i]; + this->t_ = t; + this->update(); } + template <unsigned n, typename C> + void + translation<n,C>::update() + { + for (unsigned i = 0; i < n; ++i) + this->m_(i,n) = this->t_[i]; + } # endif // ! MLN_INCLUDE_ONLY Index: trunk/milena/mln/fun/x2x/rotation.hh =================================================================== --- trunk/milena/mln/fun/x2x/rotation.hh (revision 1302) +++ trunk/milena/mln/fun/x2x/rotation.hh (revision 1303) @@ -33,12 +33,12 @@ * \brief FIXME. */ -# include <mln/fun/x2x/bijective_tr.hh> +# include <mln/core/concept/function.hh> +# include <mln/fun/internal/x2x_impl.hh> # include <mln/metal/vec.hh> # include <mln/metal/mat.hh> # include <cmath> - namespace mln { @@ -51,30 +51,29 @@ // FIXME: Doc! template <unsigned n, typename C> - struct rotation : public bijective_tr< rotation<n,C> > + struct rotation + : internal::x2x_impl_< metal::vec<n,C>, rotation<n,C> > + , public Bijection_x2x< rotation<n,C> > { + typedef fun::internal::x2x_impl_< metal::vec<n,C>, rotation<n,C> > super_; - enum {dim = n}; - - typedef metal::vec<n,C> result; typedef rotation<n,C> invert; + invert inv() const; rotation(); rotation(float alpha, unsigned dir = 2); - result operator()(const metal::vec<n,C>& v) const; - invert inv() const; + using super_::operator(); + metal::vec<n,C> operator()(const metal::vec<n,C>& v) const; void set_alpha(float alpha); void set_dir(unsigned dir); - void update(); - protected: + void update(); float alpha_; unsigned dir_; - metal::mat<n + 1,n + 1,C> m_; }; @@ -83,7 +82,9 @@ template <unsigned n, typename C> rotation<n,C>::rotation() { - m_ = metal::mat<n + 1,n + 1,C>::Id; + alpha_ = 0; + dir_ = 2; + this->m_ = h_mat<n,C>::Id; } template <unsigned n, typename C> @@ -92,6 +93,7 @@ dir_(dir) { mln_precondition(dir == 2 || n == 3); + this->m_ = h_mat<n,C>::Id; update(); } @@ -106,7 +108,7 @@ for (unsigned i = 0; i < n; ++i) hmg(i,0) = v[i]; hmg(n,0) = 1; - tmp = m_ * hmg; + tmp = this->m_ * hmg; mln_assertion(tmp(n,0) == 1); for (unsigned i = 0; i < n; ++i) res[i] = tmp(i,0); @@ -146,18 +148,14 @@ const float sin_a = sin(alpha_); const metal::vec<4,float> vec = make::vec(cos_a, -sin_a, sin_a, cos_a); - m_ = metal::mat<n + 1,n + 1,C>::Id; unsigned k = 0; for (unsigned i = 0; i < n; ++i) - { - if (i == dir_) - continue; for (unsigned j = 0; j < n; ++j) { - if (j == dir_) - continue; - m_(i, j) = vec[k++]; - } + if (j != this->dir_ && i != this->dir_) + this->m_(i, j) = vec[k++]; + else + this->m_(i, j) = (i == j); } } Index: trunk/milena/mln/fun/internal/x2x_impl.hh =================================================================== --- trunk/milena/mln/fun/internal/x2x_impl.hh (revision 1302) +++ trunk/milena/mln/fun/internal/x2x_impl.hh (revision 1303) @@ -34,7 +34,7 @@ */ # include <mln/core/concept/function.hh> -# include <mln/metal/mat.hh> +# include <mln/core/h_mat.hh> # include <mln/core/h_vec.hh> @@ -55,16 +55,19 @@ typedef V argument; typedef V result; typedef typename V::coord coord; + typedef h_mat<dim, coord> matrix; h_vec<dim, coord> operator()(const h_vec<dim, coord>& x) const { return m_ * x; } + const matrix& mat() const; + protected: x2x_impl_(); - metal::mat<dim+1, dim+1, coord> m_; // FIXME: Change mat into h_mat<dim, dim, coord>! + matrix m_; }; @@ -76,6 +79,15 @@ { } + + template <typename V, typename E> + const typename x2x_impl_<V,E>::matrix& + x2x_impl_<V,E>::mat() const + { + return m_; + } + + # endif // ! MLN_INCLUDE_ONLY } // end of namespace mln::fun::internal
participants (1)
-
Simon Nivault