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
00029
00030 #ifndef MLN_GEOM_ROTATE_HH
00031 # define MLN_GEOM_ROTATE_HH
00032
00033 # include <mln/core/concept/image.hh>
00034 # include <mln/core/concept/site_set.hh>
00035 # include <mln/core/concept/box.hh>
00036
00037 # include <mln/core/routine/extend.hh>
00038
00039 # include <mln/core/image/imorph/tr_image.hh>
00040
00041 # include <mln/accu/shape/bbox.hh>
00042
00043 # include <mln/data/paste.hh>
00044
00045 # include <mln/geom/bbox.hh>
00046
00047 # include <mln/fun/x2x/composed.hh>
00048 # include <mln/fun/x2x/rotation.hh>
00049 # include <mln/fun/x2x/translation.hh>
00050
00051 # include <mln/literal/zero.hh>
00052
00053 # include <mln/math/pi.hh>
00054
00055
00056 namespace mln
00057 {
00058
00059 namespace geom
00060 {
00061
00075
00076 template <typename I, typename Ext, typename S>
00077 mln_concrete(I)
00078 rotate(const Image<I>& input, double angle,
00079 const Ext& extension, const Site_Set<S>& output_domain);
00080
00081
00083 template <typename I, typename Ext>
00084 mln_concrete(I)
00085 rotate(const Image<I>& input, double angle, const Ext& extension);
00086
00087
00090 template <typename I>
00091 mln_concrete(I)
00092 rotate(const Image<I>& input, double angle);
00093
00094
00095
00096 # ifndef MLN_INCLUDE_ONLY
00097
00098
00099 template <typename I, typename Ext, typename S>
00100 mln_concrete(I)
00101 rotate(const Image<I>& input_, double angle,
00102 const Ext& extension_, const Site_Set<S>& output_domain_)
00103 {
00104 trace::entering("geom::rotate");
00105
00106 const I& input = exact(input_);
00107 const S& output_domain = exact(output_domain_);
00108 const mln_exact(Ext)& extension = exact(extension_);
00109
00110
00111
00112 mln_precondition(input.is_valid());
00113 mln_precondition(angle >= -360.0f && angle <= 360.0f);
00114 mlc_converts_to(mln_exact(Ext), mln_value(I))::check();
00115 mlc_is_a(S,Box)::check();
00116
00117
00118 mln_site(I) c = geom::bbox(input).center();
00119 typedef fun::x2x::translation<2,double> trans_t;
00120 trans_t
00121 t(-1 * c.to_vec()),
00122 t_1(c.to_vec());
00123
00124 typedef fun::x2x::rotation<2,double> rot_t;
00125 rot_t rot(math::pi * angle / 180.f, literal::origin);
00126
00127 typedef
00128 fun::x2x::composed<trans_t, fun::x2x::composed<rot_t, trans_t> >
00129 comp_transf_t;
00130
00131 comp_transf_t comp_transf = compose(t_1, compose(rot, t));
00132
00133 S b = output_domain;
00134
00135 if (!output_domain.is_valid())
00136 {
00137 accu::shape::bbox<mln_site(I)> accu;
00138
00139 typedef mln_site(I) P;
00140 accu.take(P(comp_transf(input.domain().pmin().to_vec())));
00141 accu.take(P(comp_transf(input.domain().pmax().to_vec())));
00142
00143 b = accu.to_result();
00144 }
00145
00146 typedef
00147 tr_image<mln_box(I), extension_val<const I>, comp_transf_t> tr_t;
00148
00149 tr_t tr = transposed_image(b, extend(input, extension), comp_transf);
00150
00151 typedef mln_site(I) P;
00152 P rpmin = P(rot(input.domain().pmin().to_vec()));
00153
00154 mln_concrete(I) output;
00155 initialize(output, tr);
00156
00157 data::paste(tr, output);
00158
00159 trace::exiting("geom::rotate");
00160 return output;
00161 }
00162
00163
00164 template <typename I, typename Ext>
00165 mln_concrete(I)
00166 rotate(const Image<I>& input, double angle, const Ext& extension)
00167 {
00168
00169
00170
00171 typedef mln_domain(I) domain_t;
00172 return rotate(input, angle, extension, domain_t());
00173 }
00174
00175
00176 template <typename I>
00177 mln_concrete(I)
00178 rotate(const Image<I>& input, double angle)
00179 {
00180 return rotate(input, angle, literal::zero);
00181 }
00182
00183
00184 # endif // ! MLN_INCLUDE_ONLY
00185
00186
00187 }
00188
00189 }
00190
00191
00192 #endif // ! MLN_GEOM_ROTATE_HH