• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

rotate.hh

00001 // Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
00002 // (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00030 
00031 #ifndef MLN_GEOM_ROTATE_HH
00032 # define MLN_GEOM_ROTATE_HH
00033 
00034 # include <mln/core/concept/image.hh>
00035 # include <mln/core/concept/site_set.hh>
00036 # include <mln/core/concept/box.hh>
00037 
00038 # include <mln/core/routine/extend.hh>
00039 
00040 # include <mln/core/image/imorph/tr_image.hh>
00041 
00042 # include <mln/accu/shape/bbox.hh>
00043 
00044 # include <mln/data/paste.hh>
00045 
00046 # include <mln/geom/bbox.hh>
00047 
00048 # include <mln/extension/duplicate.hh>
00049 
00050 # include <mln/fun/x2x/composed.hh>
00051 # include <mln/fun/x2x/rotation.hh>
00052 # include <mln/fun/x2x/translation.hh>
00053 
00054 # include <mln/literal/zero.hh>
00055 
00056 # include <mln/math/pi.hh>
00057 
00058 
00059 namespace mln
00060 {
00061 
00062   namespace geom
00063   {
00064 
00079     //
00080     template <typename I, typename Ext, typename S>
00081     mln_concrete(I)
00082     rotate(const Image<I>& input, double angle,
00083            const Ext& extension, const Site_Set<S>& output_domain);
00084 
00085 
00087     template <typename I, typename Ext>
00088     mln_concrete(I)
00089     rotate(const Image<I>& input, double angle, const Ext& extension);
00090 
00091 
00094     template <typename I>
00095     mln_concrete(I)
00096     rotate(const Image<I>& input, double angle);
00097 
00098 
00103     //
00104     template <typename B>
00105     B
00106     rotate(const Box<B>& box_, double angle, const mln_site(B)& ref);
00107 
00111     //
00112     template <typename B>
00113     B
00114     rotate(const Box<B>& box, double angle);
00115 
00116 
00117 
00118 # ifndef MLN_INCLUDE_ONLY
00119 
00120 
00121     template <typename I, typename Ext, typename S>
00122     mln_concrete(I)
00123     rotate(const Image<I>& input_, double angle,
00124            const Ext& extension_, const Site_Set<S>& output_domain_)
00125     {
00126       trace::entering("geom::rotate");
00127 
00128       const I& input = exact(input_);
00129       const S& output_domain = exact(output_domain_);
00130       const mln_exact(Ext)& extension = exact(extension_);
00131 
00132       // Do not check that output_domain_ is valid. If it is not,
00133       // further in this routine, we define a default domain.
00134       typedef mln_site(I) P;
00135       mln_precondition(P::dim == 2);
00136       mln_precondition(input.is_valid());
00137       mln_precondition(angle >= -360.0f && angle <= 360.0f);
00138 //      mlc_converts_to(mln_exact(Ext), mln_value(I))::check();
00139       mlc_is_a(S,Box)::check();
00140       // FIXME: A precondition is probably missing for the extension value.
00141 
00142       extension::duplicate(input);
00143 
00144       mln_site(I) c = geom::bbox(input).pcenter();
00145       typedef fun::x2x::translation<2,double> trans_t;
00146       trans_t
00147         t(-1 * c.to_vec()),
00148         t_1(c.to_vec());
00149 
00150       typedef fun::x2x::rotation<2,double> rot_t;
00151       rot_t rot(math::pi * angle / 180.f, literal::origin);
00152 
00153       typedef
00154         fun::x2x::composed<trans_t, fun::x2x::composed<rot_t, trans_t> >
00155         comp_transf_t;
00156 
00157       comp_transf_t comp_transf = compose(t_1, compose(rot, t));
00158 
00159       S b = output_domain;
00160       // Automatically adjusting the output domain if needed.
00161       if (!output_domain.is_valid())
00162         b = rotate(input.domain(), angle);
00163 
00164       typedef
00165         typename mln::internal::extension_type<const I,	mln_exact(Ext)>::result ext_t;
00166 
00167       typedef
00168         tr_image<mln_box(I), ext_t, comp_transf_t> tr_t;
00169 
00170       tr_t tr = transposed_image(b, ext_t(input, extension), comp_transf);
00171 
00172 
00173       mln_concrete(I) output;
00174       initialize(output, tr);
00175 
00176       data::paste(tr, output);
00177 
00178       trace::exiting("geom::rotate");
00179       return output;
00180     }
00181 
00182 
00183     template <typename I, typename Ext>
00184     mln_concrete(I)
00185     rotate(const Image<I>& input, double angle, const Ext& extension)
00186     {
00187       // Old versions of GCC (including Apple GCC 4.0.1) do not parse
00188       // correctly `mln_box(I)()'.  Hence, we need to typedef
00189       // `mln_box(I)' first.
00190       typedef mln_domain(I) domain_t;
00191       return rotate(input, angle, extension, domain_t());
00192     }
00193 
00194 
00195     template <typename I>
00196     mln_concrete(I)
00197     rotate(const Image<I>& input, double angle)
00198     {
00199       return rotate(input, angle, literal::zero);
00200     }
00201 
00202 
00203     template <typename B>
00204     B
00205     rotate(const Box<B>& box_, double angle, const mln_site(B)& ref)
00206     {
00207       trace::entering("geom::rotate");
00208 
00209       const B& box = exact(box_);
00210 
00211       typedef mln_site(B) P;
00212       mln_precondition(P::dim == 2);
00213       mln_precondition(box.is_valid());
00214       mln_precondition(angle >= -360.0f && angle <= 360.0f);
00215 
00216       typedef fun::x2x::translation<2,double> trans_t;
00217       trans_t
00218         t(-1 * ref.to_vec()),
00219         t_1(ref.to_vec());
00220 
00221       typedef fun::x2x::rotation<2,double> rot_t;
00222       rot_t rot(math::pi * angle / 180.f, literal::origin);
00223 
00224       typedef
00225         fun::x2x::composed<trans_t, fun::x2x::composed<rot_t, trans_t> >
00226         comp_transf_t;
00227 
00228       comp_transf_t comp_transf = compose(t_1, compose(rot, t));
00229 
00230       accu::shape::bbox<P> accu;
00231 
00232       P
00233         top_right(box.pmin().row(),
00234                   box.pmax().col()),
00235         bot_left(box.pmax().row(),
00236                  box.pmin().col());
00237 
00238       accu.take(P(comp_transf(box.pmin().to_vec())));
00239       accu.take(P(comp_transf(top_right.to_vec())));
00240       accu.take(P(comp_transf(bot_left.to_vec())));
00241       accu.take(P(comp_transf(box.pmax().to_vec())));
00242 
00243       B output = accu.to_result();
00244 
00245       trace::exiting("geom::rotate");
00246       return output;
00247     }
00248 
00249 
00250     template <typename B>
00251     B
00252     rotate(const Box<B>& box, double angle)
00253     {
00254       return rotate(box, angle, exact(box).pcenter());
00255     }
00256 
00257 
00258 
00259 # endif // ! MLN_INCLUDE_ONLY
00260 
00261 
00262   } // end of namespace mln::geom
00263 
00264 } // end of namespace mln
00265 
00266 
00267 #endif // ! MLN_GEOM_ROTATE_HH

Generated on Tue Oct 4 2011 15:24:22 for Milena (Olena) by  doxygen 1.7.1