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_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;
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
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
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
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
00278
00279
00280
00281
00282 float v = 1 - y * y / yr2;
00283 if (v < 0) v = 0;
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 }
00314
00315 #endif // OLENA_CORE_WINDOW2D_HH