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
00027
00028 #ifndef OLENA_GEOM_ROTATE_HH
00029 # define OLENA_GEOM_ROTATE_HH
00030
00031 # include <cmath>
00032 # include <iostream>
00033
00034 # include <oln/core/image2d.hh>
00035 # include <oln/core/fpoint2d.hh>
00036
00037 namespace oln {
00038
00039 namespace geom {
00040
00041 template <class T, class Access>
00042 struct ftor_rotate
00043 {
00044 private:
00045 fpoint2d_access<T, Access> interp;
00046 point2d center;
00047 double cos_angle, sin_angle, a, b;
00048
00049 public:
00050 ftor_rotate(const point2d& center_,
00051 const fpoint2d_access<T, Access>& interp_,
00052 const double rad_angle_) :
00053 interp(interp_),
00054 center(center_)
00055 {
00056 cos_angle = cos(-rad_angle_);
00057 sin_angle = sin(-rad_angle_);
00058
00059 std::cout << sin_angle << " " << cos_angle << std::endl;
00060
00061 a = double(center.row());
00062 b = double(center.col());
00063
00064 }
00065
00066 ftor_rotate() {}
00067
00068 ftor_rotate(const ftor_rotate<T, Access>& rhs)
00069 {
00070 interp = rhs.interp;
00071 center = rhs.center;
00072 cos_angle = rhs.cos_angle;
00073 sin_angle = rhs.sin_angle;
00074 a = rhs.a;
00075 b = rhs.b;
00076 }
00077
00078 const T
00079 operator()(const image2d<T>& ima,
00080 const point2d p) const
00081 {
00082 double x, y;
00083 double c, d;
00084
00085 c = a + ima.size().nrows() / 2;
00086 d = b + ima.size().ncols() / 2;
00087
00088 x = cos_angle * double(p.row()) - sin_angle * double(p.col()) -
00089 c * cos_angle + d * sin_angle + c;
00090 y = sin_angle * double(p.row()) + cos_angle * double(p.col()) -
00091 c * sin_angle - d * cos_angle + d;
00092
00093 return interp(ima, fpoint2d<double>(x, y));
00094 }
00095 };
00096
00097 template <class T, class Access>
00098 struct rotate
00099 {
00100 typedef image2d<T> im_type;
00101
00102 im_type
00103 operator()(const im_type& ima,
00104 const point2d center,
00105 double rad_angle,
00106 fpoint2d_access<T, Access> interp)
00107 {
00108 im_type res(ima.size());
00109 ftor_rotate<T, Access> f(center, interp, rad_angle);
00110 oln_iter_type(im_type) it(res);
00111
00112 for_all(it)
00113 {
00114 res[it] = f(ima, point2d(it.row(), it.col()));
00115 }
00116 return res;
00117 }
00118 };
00119
00120
00121 template <class T, class Access>
00122 struct ftor_rotate_enlarge
00123 {
00124 private:
00125 fpoint2d_access<T, Access> interp;
00126 point2d center;
00127 double cos_angle;
00128 double sin_angle;
00129 double a;
00130 double b;
00131
00132 public:
00133 ftor_rotate_enlarge(const point2d& center_,
00134 const fpoint2d_access<T, Access>& interp_,
00135 const double rad_angle_) :
00136 interp(interp_),
00137 center(center_)
00138 {
00139 cos_angle = cos(-rad_angle_);
00140 sin_angle = sin(-rad_angle_);
00141 a = double(center.row());
00142 b = double(center.col());
00143 }
00144
00145 ftor_rotate_enlarge()
00146 {}
00147
00148 ftor_rotate_enlarge(const ftor_rotate_enlarge& rhs) :
00149 interp(rhs.interp),
00150 center(rhs.center)
00151 {
00152 cos_angle = rhs.cos_angle;
00153 sin_angle = rhs.sin_angle;
00154 a = rhs.a;
00155 b = rhs.b;
00156 }
00157
00158 T
00159 operator()(const image2d<T>& ima,
00160 const point2d p)
00161 {
00162 double x, y;
00163 double c, d;
00164 double rrows = ima.size().nrows() * cos_angle +
00165 ima.size().ncols() * -sin_angle;
00166 double rcols = ima.size().nrows() * -sin_angle +
00167 ima.size().ncols() * cos_angle;
00168 double vt = (rrows - ima.size().nrows()) / 2;
00169 double ht = (rcols - ima.size().ncols()) / 2;
00170
00171 c = a + ima.size().nrows() / 2;
00172 d = b + ima.size().ncols() / 2;
00173
00174 x = cos_angle * double(p.row() - vt) - sin_angle * double(p.col() - ht) -
00175 c * cos_angle + d * sin_angle + c;
00176 y = sin_angle * double(p.row() - vt) + cos_angle * double(p.col() - ht) -
00177 c * sin_angle - d * cos_angle + d;
00178
00179 return interp(ima, fpoint2d<double>(x, y));
00180 }
00181 };
00182
00183
00184
00185
00186 template <class T, class Access>
00187 struct rotate_enlarge
00188 {
00189
00190 typedef image2d<T> im_type;
00191
00192 im_type
00193 operator()(const im_type& ima,
00194 const point2d center,
00195 double rad_angle,
00196 fpoint2d_access<T, Access> interp)
00197 {
00198 im_type res(image2d_size(int(ima.size().nrows() * cos(rad_angle) +
00199 ima.size().ncols() * sin(rad_angle)),
00200 int(ima.size().nrows() * sin(rad_angle) +
00201 ima.size().ncols() * cos(rad_angle)),
00202 0));
00203
00204 oln_iter_type(im_type) it(res);
00205 ftor_rotate_enlarge<T, Access> f(center, interp, rad_angle);
00206
00207 for_all(it)
00208 {
00209 res[it] = f(ima, point2d(it.row(), it.col()));
00210 }
00211 return res;
00212 }
00213 };
00214
00215 }
00216 }
00217
00218
00219 #endif // !OLENA_CORE_FPOINT2D_HH