URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2007-10-10 Simon Nivault <simon.nivault(a)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