31 #ifndef MLN_GEOM_ROTATE_HH
32 # define MLN_GEOM_ROTATE_HH
34 # include <mln/core/concept/image.hh>
35 # include <mln/core/concept/site_set.hh>
36 # include <mln/core/concept/box.hh>
38 # include <mln/core/routine/extend.hh>
40 # include <mln/core/image/imorph/tr_image.hh>
42 # include <mln/accu/shape/bbox.hh>
44 # include <mln/data/paste.hh>
46 # include <mln/geom/bbox.hh>
47 # include <mln/geom/top_right.hh>
48 # include <mln/geom/bottom_left.hh>
50 # include <mln/extension/duplicate.hh>
52 # include <mln/fun/x2x/composed.hh>
53 # include <mln/fun/x2x/rotation.hh>
54 # include <mln/fun/x2x/translation.hh>
56 # include <mln/literal/zero.hh>
58 # include <mln/math/pi.hh>
84 template <
typename I,
typename Ext,
typename S>
86 rotate(const Image<I>& input,
double angle,
87 const Ext& extension, const Site_Set<S>& output_domain);
94 template <typename I, typename Ext>
96 rotate(const Image<I>& input,
double angle, const Ext& extension);
104 template <typename I>
106 rotate(const Image<I>& input,
double angle);
116 template <typename B>
118 rotate(const Box<B>& box_,
double angle, const mln_site(B)& ref);
126 template <typename B>
132 # ifndef MLN_INCLUDE_ONLY
135 template <
typename I,
typename Ext,
typename S>
137 rotate(const Image<I>& input_,
double angle,
138 const Ext& extension_, const Site_Set<S>& output_domain_)
140 mln_trace(
"geom::rotate");
142 const I& input =
exact(input_);
143 const S& output_domain =
exact(output_domain_);
144 const mln_exact(Ext)& extension =
exact(extension_);
148 typedef mln_site(I) P;
149 mln_precondition(input.is_valid());
150 mln_precondition(angle >= -360.0f && angle <= 360.0f);
152 mlc_is_a(S,Box)::check();
157 mln_site(I) c = geom::
bbox(input).pcenter();
158 typedef fun::x2x::translation<P::dim,
double> trans_t;
163 typedef fun::x2x::rotation<P::dim,
double> rot_t;
164 rot_t rot(math::
pi * angle / 180.f, literal::origin);
167 fun::x2x::composed<trans_t, fun::x2x::composed<rot_t, trans_t> >
174 if (!output_domain.is_valid())
175 b =
rotate(input.domain(), angle);
178 typename mln::internal::extension_type<const I, mln_exact(Ext)>::result ext_t;
181 tr_image<mln_box(I), ext_t, comp_transf_t> tr_t;
183 tr_t tr = transposed_image(b, ext_t(input, extension), comp_transf);
186 mln_concrete(I) output;
195 template <typename I, typename Ext>
197 rotate(const Image<I>& input,
double angle, const Ext& extension)
202 typedef mln_domain(I) domain_t;
203 return
rotate(input, angle, extension, domain_t());
207 template <typename I>
209 rotate(const Image<I>& input,
double angle)
215 template <
typename B>
217 rotate(
const Box<B>& box_,
double angle,
const mln_site(B)& ref)
219 mln_trace(
"geom::rotate");
221 const B& box =
exact(box_);
223 typedef mln_site(B) P;
224 mln_precondition(box.is_valid());
225 mln_precondition(angle >= -360.0f && angle <= 360.0f);
227 typedef fun::x2x::translation<P::dim,
double> trans_t;
229 t(-1 * ref.to_vec()),
232 typedef fun::x2x::rotation<P::dim,
double> rot_t;
233 rot_t rot(math::
pi * angle / 180.f, literal::origin);
236 fun::x2x::composed<trans_t, fun::x2x::composed<rot_t, trans_t> >
241 accu::shape::
bbox<P> accu;
247 accu.take(P(comp_transf(box.pmin().to_vec())));
248 accu.take(P(comp_transf(
top_right.to_vec())));
249 accu.take(P(comp_transf(bot_left.to_vec())));
250 accu.take(P(comp_transf(box.pmax().to_vec())));
252 B output = accu.to_result();
258 template <typename B>
260 rotate(const Box<B>& box,
double angle)
267 # endif // ! MLN_INCLUDE_ONLY
275 #endif // ! MLN_GEOM_ROTATE_HH