fpoint2d.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_CORE_FPOINT2D_HH
00029 # define OLENA_CORE_FPOINT2D_HH
00030 
00031 # include <iostream>
00032 
00033 # include <oln/core/image2d.hh>
00034 # include <oln/core/abstract/image.hh>
00035 # include <oln/core/point2d.hh>
00036 
00037 namespace oln {
00038 
00039 
00040   // fwd decl
00041   template <class F>
00042   class fpoint2d;
00043 
00044   template <class F>
00045   class fdpoint2d;
00046 
00052   template<class F>
00053   struct point_traits<fpoint2d<F> >
00054   {
00055     enum { dim = 2 };
00056     typedef fdpoint2d<F> dpoint_type;
00057   };
00058 
00064   template <class F>
00065   class fpoint2d
00066   {
00067   private:
00068 
00069     F coord_[2];
00070 
00071   public:
00072 
00073     typedef fpoint2d<F> exact_type;
00074     typedef fpoint2d<F> self_type;
00075     typedef fdpoint2d<F> dpoint_type;
00076 
00077     fpoint2d(F x, F y)
00078     {
00079       coord_[0] = x;
00080       coord_[1] = y;
00081     }
00082 
00083     fpoint2d()
00084     {}
00085 
00087 
00088     F
00089     row() const
00090     {
00091       return coord_[0];
00092     }
00093 
00094     F&
00095     row()
00096     {
00097       return coord_[0];
00098     }
00099 
00100     F
00101     col() const
00102     {
00103       return coord_[1];
00104     }
00105 
00106     F&
00107     col()
00108     {
00109       return coord_[1];
00110     }
00111 
00112     F
00113     nth(const unsigned dim) const
00114     {
00115       assert(dim < 2);
00116       return coord_[dim];
00117     }
00118 
00120 
00121     F&
00122     nth(const unsigned dim)
00123     {
00124       assert(dim < 2);
00125       return coord_[dim];
00126     }
00127 
00128     exact_type
00129     operator-() const
00130     {
00131       return exact_type(-coord_[0], -coord_[1]);
00132     }
00133 
00134     exact_type&
00135     operator+=(const dpoint_type& dp)
00136     {
00137       row() += dp.row();
00138       col() += dp.col();
00139       return *this;
00140     }
00141 
00142     exact_type&
00143     operator-=(const dpoint_type& dp)
00144     {
00145       row() += dp.row();
00146       col() += dp.col();
00147       return *this;
00148     }
00149 
00150     dpoint_type
00151     operator-(const self_type& p) const
00152     {
00153       dpoint_type dp(row() - p.row(), col() - p.col());
00154       return dp;
00155     }
00156 
00157 
00158     exact_type
00159     operator-(const dpoint_type& dp) const
00160     {
00161       exact_type p = *this;
00162       p += dp;
00163       return p;
00164     }
00165 
00166     dpoint_type
00167     operator+(const self_type& p) const
00168     {
00169       dpoint_type dp(row() + p.row(), col() + p.col());
00170       return dp;
00171     }
00172 
00173     exact_type
00174     operator+(const dpoint_type& dp) const
00175     {
00176       exact_type p = *this;
00177       p -= dp;
00178       return p;
00179     }
00180 
00181 
00188     bool
00189     operator==(const self_type& p) const
00190     {
00191       return p.nth(0) == coord_[0] && p.nth(1) == coord_[1];
00192     }
00193 
00194 
00202     bool
00203     operator!=(const self_type& p) const
00204     {
00205       return !(p.nth(0) == coord_[0] && p.nth(1) == coord_[1]);
00206     }
00207 
00208 
00209 
00210   };
00211 
00212   template <class T>
00213   struct func_traits
00214   {
00215   };
00216 
00217   template <class T, class F>
00218   struct nearest;
00219 
00220   template <class T, class F>
00221   struct bilinear;
00222 
00223   template <class T, class F>
00224   struct func_traits<nearest<T, F> >
00225   {
00226     typedef F f_type;
00227   };
00228 
00229   template <class T, class F>
00230   struct func_traits<bilinear<T, F> >
00231   {
00232     typedef F f_type;
00233   };
00234 
00235   template <class T, class Exact>
00236   struct fpoint2d_access
00237   {
00238 
00239     typedef typename func_traits<Exact>::f_type f_type;
00240 
00241     const T operator()(const image2d<T> &ima, const fpoint2d<f_type> p) const
00242     {
00243       return (static_cast<const Exact *>(this))->access_impl(ima, p);
00244     }
00245 
00246   };
00247 
00248 
00249   template <class T, class F>
00250   struct nearest : public fpoint2d_access<T, nearest<T, F> >
00251   {
00252 
00253     const T access_impl(const image2d<T> &ima, const fpoint2d<F> p) const
00254     {
00255 
00256       point2d p2d(int(p.nth(0)), int(p.nth(1)));
00257 
00258       if (ima.hold(p2d))
00259         return ima[p2d];
00260       else // FIXME : should be ntg_max_val(T)
00261         return ntg::rgb_8(255, 255, 255);
00262     }
00263 
00264   };
00265 
00266   template <class T, class F>
00267   struct bilinear : public fpoint2d_access<T, bilinear<T, F> >
00268   {
00269 
00270     const T access_impl(const image2d<T> &ima, const fpoint2d<F> p) const
00271     {
00272       double x = floorf(p.nth(0));
00273       double y = floorf(p.nth(1));
00274 
00275       int a = int(x);
00276       int b = int(y);
00277 
00278 
00279       if (ima.hold(point2d(a, b)) && ima.hold(point2d(a + 1, b + 1)))
00280         {
00281           int res[3];
00282 
00283           res[0] = int((double(ima(a, b)[0]) * (x + 1 - p.nth(0)) +
00284                         double(ima(a + 1, b)[0]) * (p.nth(0) - x)) * (y + 1 - p.nth(1)) +
00285                        (double(ima(a, b + 1)[0]) * (p.nth(0) - x) +
00286                         double(ima(a + 1, b + 1)[0]) * (x + 1 - p.nth(0))) * (p.nth(1) - y));
00287           res[1] = int((double(ima(a, b)[1]) * (x + 1 - p.nth(0)) +
00288                         double(ima(a + 1, b)[1]) * (p.nth(0) - x)) * (y + 1 - p.nth(1)) +
00289                        (double(ima(a, b + 1)[1]) * (p.nth(0) - x) +
00290                         double(ima(a + 1, b + 1)[1]) * (x + 1 - p.nth(0))) * (p.nth(1) - y));
00291           res[2] = int((double(ima(a, b)[2]) * (x + 1 - p.nth(0)) +
00292                         double(ima(a + 1, b)[2]) * (p.nth(0) - x)) * (y + 1 - p.nth(1)) +
00293                        (double(ima(a, b + 1)[2]) * (p.nth(0) - x) +
00294                         double(ima(a + 1, b + 1)[2]) * (x + 1 - p.nth(0))) * (p.nth(1) - y));
00295           return ntg::rgb_8(res[0], res[1], res[2]);
00296         }
00297       else if (ima.hold(point2d(a, b)))
00298         return ima(a, b);
00299       else // FIXME : should be ntg_max_val(T)
00300         return ntg::rgb_8(255, 255, 255);
00301     }
00302 
00303   };
00304 
00305 
00306 } // end of oln
00307 
00308 
00310 
00311 template <class F>
00312 inline std::ostream&
00313 operator<<(std::ostream& o, const oln::fpoint2d<F>& p)
00314 {
00315   return o << '(' << p.nth(0) << ',' << p.nth(1) << ')';
00316 }
00317 
00318 
00319 
00320 
00321 
00322 #endif // ! OLENA_CORE_FPOINT2D_HH

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