window2d.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, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, 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_WINDOW2D_HH
00029 # define OLENA_CORE_WINDOW2D_HH
00030 
00031 # include <oln/core/point2d.hh>
00032 # include <oln/core/dpoint2d.hh>
00033 # include <oln/core/abstract/windownd.hh>
00034 # include <oln/core/winiter.hh>
00035 # include <oln/core/accum.hh>
00036 # include <oln/io/readable.hh>
00037 # include <algorithm>
00038 
00039 namespace oln {
00040 
00041   class window2d; // forward declaration
00042 
00046   template<>
00047   struct struct_elt_traits<window2d>: public
00048   struct_elt_traits<abstract::windownd<window2d> >
00049   {
00050     enum { dim = 2 }; 
00051     typedef point2d point_type; 
00052     typedef dpoint2d dpoint_type; 
00053     typedef winiter< window2d > iter_type; 
00054     typedef winneighb< window2d > neighb_type; 
00055   };
00056 
00063   class window2d : public abstract::windownd< window2d >
00064   {
00065 
00066   public:
00067 
00068     typedef abstract::windownd<window2d > super_type;
00070     typedef window2d self_type; 
00071 
00077     typedef struct_elt_traits< self_type >::iter_type   iter_type;
00078 
00079     typedef struct_elt_traits< self_type >::neighb_type neighb_type;
00080     typedef struct_elt_traits< self_type >::neighb_type neighb_type;
00082 
00088     typedef struct_elt_traits< self_type >::dpoint_type dpoint_type;
00089 
00090     friend class abstract::window_base<abstract::window<window2d>, window2d>;
00091 
00099     window2d&
00100     add(const dpoint_type& dp)
00101     {
00102       return this->exact().add_(dp);
00103     }
00104 
00114     window2d&
00115     add(coord row, coord col)
00116     {
00117       dpoint_type dp(row, col);
00118       return add(dp);
00119     }
00120 
00124     window2d() : super_type()
00125     {}
00126 
00131     window2d(unsigned size) : super_type(size)
00132     {}
00133 
00139     window2d(unsigned n, const coord crd[]) : super_type(n)
00140     {
00141       for (unsigned i = 0; i < 2 * n; i += 2)
00142         add(dpoint_type(crd[i], crd[i+1]));
00143     }
00144 
00145     // This constructor is used by functions of io
00146     window2d(const io::internal::anything& r) : super_type()
00147     {
00148       r.assign(*this);
00149     }
00150 
00152     static std::string
00153     name()
00154     {
00155       return std::string("window2d");
00156     }
00157 
00158   protected:
00159 
00168     coord
00169     delta_update_(const dpoint_type& dp)
00170     {
00171       delta_(abs(dp.row()));
00172       delta_(abs(dp.col()));
00173       return delta_;
00174     }
00175 
00176   };
00177 
00178 
00179   // std win
00180 
00185   inline const window2d&
00186   win_c4_only()
00187   {
00188     static const coord crd[] = { -1,0,  0,-1, 0,1,  1,0 };
00189     static const window2d win(4, crd);
00190     return win;
00191   }
00192 
00199   inline const window2d&
00200   win_c4p()
00201   {
00202     static const coord crd[] = { -1,0,  0,-1, 0,0, 0,1,  1,0 };
00203     static const window2d win(5, crd);
00204     return win;
00205   }
00206 
00211   inline const window2d&
00212   win_c8_only()
00213   {
00214     static const coord crd[] = { -1,-1, -1,0, -1,1,  0,-1, 0,1,  1,-1,  1,0,  1,1 };
00215     static const window2d win(8, crd);
00216     return win;
00217   }
00218 
00225   inline const window2d&
00226   win_c8p()
00227   {
00228     static const coord crd[] = { -1,-1, -1,0, -1,1,  0,-1, 0,0, 0,1,  1,-1,  1,0,  1,1 };
00229     static const window2d win(9, crd);
00230     return win;
00231   }
00232 
00233   // mk_win's
00234 
00245   inline window2d
00246   mk_win_rectangle(unsigned nrows, unsigned ncols)
00247   {
00248     precondition(nrows >= 3 && (nrows % 2) == 1);
00249     precondition(ncols >= 3 && (ncols % 2) == 1);
00250     window2d win(nrows * ncols);
00251     int half_nrows = nrows / 2, half_ncols = ncols / 2;
00252     for (coord row = - half_nrows; row <= half_nrows; ++row)
00253       for (coord col = - half_ncols; col <= half_ncols; ++col)
00254         win.add(row, col);
00255     return win;
00256   }
00257 
00265   inline window2d
00266   mk_win_ellipse(float yradius, float xradius)
00267   {
00268     precondition(yradius > 0);
00269     precondition(xradius > 0);
00270 
00271     window2d win;
00272     coord ymax = (coord)roundf(yradius);
00273     float yr2 = yradius * yradius;
00274     for (coord y = -ymax; y <= ymax; ++y)
00275       {
00276         /*
00277               x^2         y^2
00278            --------- + --------- = 1
00279            xradius^2   yradius^2
00280 
00281         */
00282         float v = 1 - y * y / yr2;
00283         if (v < 0) v = 0;       // Can happen because ymax has been rounded.
00284         coord xmax = (coord)roundf(xradius * sqrtf(v));
00285         for (coord x = -xmax; x <= xmax; ++x)
00286           win.add(y, x);
00287       }
00288     return win;
00289   }
00290 
00296   inline window2d
00297   mk_win_square(unsigned width)
00298   {
00299     return mk_win_rectangle(width, width);
00300   }
00301 
00307   inline window2d
00308   mk_win_disc(float radius)
00309   {
00310     return mk_win_ellipse(radius, radius);
00311   }
00312 
00313 } // end of oln
00314 
00315 #endif // OLENA_CORE_WINDOW2D_HH

Generated on Thu Apr 15 20:13:15 2004 for Olena by doxygen 1.3.6-20040222