Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
rotate.hh
1 // Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
2 // (LRDE)
3 //
4 // This file is part of Olena.
5 //
6 // Olena is free software: you can redistribute it and/or modify it under
7 // the terms of the GNU General Public License as published by the Free
8 // Software Foundation, version 2 of the License.
9 //
10 // Olena is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
17 //
18 // As a special exception, you may use this file as part of a free
19 // software project without restriction. Specifically, if other files
20 // instantiate templates or use macros or inline functions from this
21 // file, or you compile this file and link it with other files to produce
22 // an executable, this file does not by itself cause the resulting
23 // executable to be covered by the GNU General Public License. This
24 // exception does not however invalidate any other reasons why the
25 // executable file might be covered by the GNU General Public License.
26 
30 
31 #ifndef MLN_GEOM_ROTATE_HH
32 # define MLN_GEOM_ROTATE_HH
33 
34 # include <mln/core/concept/image.hh>
35 # include <mln/core/concept/site_set.hh>
36 # include <mln/core/concept/box.hh>
37 
38 # include <mln/core/routine/extend.hh>
39 
40 # include <mln/core/image/imorph/tr_image.hh>
41 
42 # include <mln/accu/shape/bbox.hh>
43 
44 # include <mln/data/paste.hh>
45 
46 # include <mln/geom/bbox.hh>
47 
48 # include <mln/extension/duplicate.hh>
49 
50 # include <mln/fun/x2x/composed.hh>
51 # include <mln/fun/x2x/rotation.hh>
52 # include <mln/fun/x2x/translation.hh>
53 
54 # include <mln/literal/zero.hh>
55 
56 # include <mln/math/pi.hh>
57 
58 
59 namespace mln
60 {
61 
62  namespace geom
63  {
64 
79  //
80  template <typename I, typename Ext, typename S>
81  mln_concrete(I)
82  rotate(const Image<I>& input, double angle,
83  const Ext& extension, const Site_Set<S>& output_domain);
84 
85 
87  template <typename I, typename Ext>
88  mln_concrete(I)
89  rotate(const Image<I>& input, double angle, const Ext& extension);
90 
91 
94  template <typename I>
95  mln_concrete(I)
96  rotate(const Image<I>& input, double angle);
97 
98 
103  //
104  template <typename B>
105  B
106  rotate(const Box<B>& box_, double angle, const mln_site(B)& ref);
107 
111  //
112  template <typename B>
113  B
114  rotate(const Box<B>& box, double angle);
115 
116 
117 
118 # ifndef MLN_INCLUDE_ONLY
119 
120 
121  template <typename I, typename Ext, typename S>
122  mln_concrete(I)
123  rotate(const Image<I>& input_, double angle,
124  const Ext& extension_, const Site_Set<S>& output_domain_)
125  {
126  trace::entering("geom::rotate");
127 
128  const I& input = exact(input_);
129  const S& output_domain = exact(output_domain_);
130  const mln_exact(Ext)& extension = exact(extension_);
131 
132  // Do not check that output_domain_ is valid. If it is not,
133  // further in this routine, we define a default domain.
134  typedef mln_site(I) P;
135  mln_precondition(P::dim == 2);
136  mln_precondition(input.is_valid());
137  mln_precondition(angle >= -360.0f && angle <= 360.0f);
138 // mlc_converts_to(mln_exact(Ext), mln_value(I))::check();
139  mlc_is_a(S,Box)::check();
140  // FIXME: A precondition is probably missing for the extension value.
141 
142  extension::duplicate(input);
143 
144  mln_site(I) c = geom::bbox(input).pcenter();
145  typedef fun::x2x::translation<2,double> trans_t;
146  trans_t
147  t(-1 * c.to_vec()),
148  t_1(c.to_vec());
149 
150  typedef fun::x2x::rotation<2,double> rot_t;
151  rot_t rot(math::pi * angle / 180.f, literal::origin);
152 
153  typedef
155  comp_transf_t;
156 
157  comp_transf_t comp_transf = compose(t_1, compose(rot, t));
158 
159  S b = output_domain;
160  // Automatically adjusting the output domain if needed.
161  if (!output_domain.is_valid())
162  b = rotate(input.domain(), angle);
163 
164  typedef
165  typename mln::internal::extension_type<const I, mln_exact(Ext)>::result ext_t;
166 
167  typedef
169 
170  tr_t tr = transposed_image(b, ext_t(input, extension), comp_transf);
171 
172 
173  mln_concrete(I) output;
174  initialize(output, tr);
175 
176  data::paste(tr, output);
177 
178  trace::exiting("geom::rotate");
179  return output;
180  }
181 
182 
183  template <typename I, typename Ext>
184  mln_concrete(I)
185  rotate(const Image<I>& input, double angle, const Ext& extension)
186  {
187  // Old versions of GCC (including Apple GCC 4.0.1) do not parse
188  // correctly `mln_box(I)()'. Hence, we need to typedef
189  // `mln_box(I)' first.
190  typedef mln_domain(I) domain_t;
191  return rotate(input, angle, extension, domain_t());
192  }
193 
194 
195  template <typename I>
196  mln_concrete(I)
197  rotate(const Image<I>& input, double angle)
198  {
199  return rotate(input, angle, literal::zero);
200  }
201 
202 
203  template <typename B>
204  B
205  rotate(const Box<B>& box_, double angle, const mln_site(B)& ref)
206  {
207  trace::entering("geom::rotate");
208 
209  const B& box = exact(box_);
210 
211  typedef mln_site(B) P;
212  mln_precondition(P::dim == 2);
213  mln_precondition(box.is_valid());
214  mln_precondition(angle >= -360.0f && angle <= 360.0f);
215 
216  typedef fun::x2x::translation<2,double> trans_t;
217  trans_t
218  t(-1 * ref.to_vec()),
219  t_1(ref.to_vec());
220 
221  typedef fun::x2x::rotation<2,double> rot_t;
222  rot_t rot(math::pi * angle / 180.f, literal::origin);
223 
224  typedef
226  comp_transf_t;
227 
228  comp_transf_t comp_transf = compose(t_1, compose(rot, t));
229 
231 
232  P
233  top_right(box.pmin().row(),
234  box.pmax().col()),
235  bot_left(box.pmax().row(),
236  box.pmin().col());
237 
238  accu.take(P(comp_transf(box.pmin().to_vec())));
239  accu.take(P(comp_transf(top_right.to_vec())));
240  accu.take(P(comp_transf(bot_left.to_vec())));
241  accu.take(P(comp_transf(box.pmax().to_vec())));
242 
243  B output = accu.to_result();
244 
245  trace::exiting("geom::rotate");
246  return output;
247  }
248 
249 
250  template <typename B>
251  B
252  rotate(const Box<B>& box, double angle)
253  {
254  return rotate(box, angle, exact(box).pcenter());
255  }
256 
257 
258 
259 # endif // ! MLN_INCLUDE_ONLY
260 
261 
262  } // end of namespace mln::geom
263 
264 } // end of namespace mln
265 
266 
267 #endif // ! MLN_GEOM_ROTATE_HH