rotate.hh

00001 // Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016 // Boston, MA 02110-1301, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
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

Generated on Tue Feb 20 20:20:31 2007 for Olena by  doxygen 1.5.1