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_CORE_NEIGHBORHOOD2D_HH
00029 # define OLENA_CORE_NEIGHBORHOOD2D_HH
00030
00031 # include <oln/core/abstract/neighborhoodnd.hh>
00032 # include <oln/core/winiter.hh>
00033 # include <oln/core/accum.hh>
00034 # include <oln/core/window2d.hh>
00035 # include <oln/io/readable.hh>
00036 # include <algorithm>
00037
00038 namespace oln {
00039
00040 class neighborhood2d;
00041
00045 template<>
00046 struct struct_elt_traits<neighborhood2d>: public
00047 struct_elt_traits<abstract::neighborhoodnd<neighborhood2d> >
00048 {
00049 enum { dim = 2 };
00050 typedef point2d point_type;
00051 typedef dpoint2d dpoint_type;
00052 typedef winiter< neighborhood2d > iter_type;
00053 typedef winneighb< neighborhood2d > neighb_type;
00054 typedef window2d win_type;
00055 };
00056
00065 class neighborhood2d :
00066 public abstract::neighborhoodnd< neighborhood2d >
00067 {
00068 public:
00069
00070 typedef abstract::neighborhoodnd< neighborhood2d > super_type;
00072 typedef neighborhood2d self_type;
00073
00079 typedef struct_elt_traits< self_type >::iter_type iter_type;
00080
00081 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::neighborhood<neighborhood2d>, neighborhood2d>;
00091
00099 neighborhood2d&
00100 add(const dpoint_type& dp)
00101 {
00102 this->exact().add_(dp);
00103 return this->exact().add_(-dp);
00104 }
00105
00114 neighborhood2d&
00115 add(coord row, coord col)
00116 {
00117 return this->add(dpoint_type(row, col));
00118 }
00119
00123 neighborhood2d() : super_type()
00124 {}
00125
00130 neighborhood2d(unsigned size) : super_type(size)
00131 {}
00132
00138 neighborhood2d(unsigned n, const coord crd[]) : super_type(n)
00139 {
00140 for (unsigned i = 0; i < 2 * n; i += 2)
00141 add(dpoint_type(crd[i], crd[i+1]));
00142 }
00143
00144
00145 neighborhood2d(const io::internal::anything& r) : super_type()
00146 {
00147 r.assign(*this);
00148 }
00149
00151 static std::string
00152 name()
00153 {
00154 return std::string("neighborhood2d");
00155 }
00156
00157 protected:
00158
00167 coord
00168 delta_update_(const dpoint_type& dp)
00169 {
00170 delta_(abs(dp.row()));
00171 delta_(abs(dp.col()));
00172 return delta_;
00173 }
00174
00175 };
00176
00177
00178
00183 inline const neighborhood2d&
00184 neighb_c4()
00185 {
00186 static const coord crd[] = { 0,1, 1,0 };
00187 static const neighborhood2d neighb(2, crd);
00188 return neighb;
00189 }
00190
00191
00197 inline const neighborhood2d&
00198 neighb_c8()
00199 {
00200 static const coord crd[] = { 0,1, 1,1, 1,0, 1,-1 };
00201 static const neighborhood2d neighb(4, crd);
00202 return neighb;
00203 }
00204
00205
00206
00217 inline neighborhood2d
00218 mk_neighb_rectangle(unsigned nrows, unsigned ncols)
00219 {
00220 precondition(nrows >= 3 && (nrows % 2) == 1);
00221 precondition(ncols >= 3 && (ncols % 2) == 1);
00222 neighborhood2d neighb(nrows * ncols);
00223 int half_nrows = nrows / 2, half_ncols = ncols / 2;
00224 for (coord row = - half_nrows; row <= half_nrows; ++row)
00225 for (coord col = (row <= 0)? 1 : 0; col <= half_ncols; ++col)
00226 neighb.add(row, col);
00227 return neighb;
00228 }
00229
00235 inline neighborhood2d
00236 mk_neighb_square(unsigned width)
00237 {
00238 return mk_neighb_rectangle(width, width);
00239 }
00240
00246 inline window2d
00247 mk_win_from_neighb(const neighborhood2d& n)
00248 {
00249 window2d win(n.card());
00250 for (unsigned i = 0; i < n.card(); ++i)
00251 win.add(n.dp(i));
00252 return win;
00253 }
00254
00255 }
00256
00257 #endif // OLENA_CORE_NEIGHBORHOOD2D_HH