00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00133
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
00139 mlc_is_a(S,Box)::check();
00140
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
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
00188
00189
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 }
00263
00264 }
00265
00266
00267 #endif // ! MLN_GEOM_ROTATE_HH