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_WINDOW3D_HH
00029 # define OLENA_CORE_WINDOW3D_HH
00030
00031 # include <oln/core/point3d.hh>
00032 # include <oln/core/dpoint3d.hh>
00033 # include <oln/core/abstract/windownd.hh>
00034 # include <oln/core/winiter.hh>
00035 # include <oln/core/accum.hh>
00036
00037 # include <algorithm>
00038
00039 namespace oln {
00040
00041 class window3d;
00042
00046 template<>
00047 struct struct_elt_traits<window3d>: public
00048 struct_elt_traits<abstract::windownd<window3d> >
00049 {
00050 enum { dim = 3 };
00051 typedef point3d point_type;
00052 typedef dpoint3d dpoint_type;
00053 typedef winiter< window3d > iter_type;
00054 typedef winneighb< window3d > neighb_type;
00055 };
00056
00063 class window3d : public abstract::windownd< window3d >
00064 {
00065
00066 public:
00067
00068 typedef abstract::windownd< window3d > super_type;
00070 typedef window3d 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;
00081
00087 typedef struct_elt_traits< self_type >::dpoint_type dpoint_type;
00088
00089 friend class abstract::window_base<abstract::window<window3d>, window3d>;
00090
00098 window3d& add(const dpoint_type& dp)
00099 {
00100 return this->exact().add_(dp);
00101 }
00102
00113 window3d& add(coord slice, coord row, coord col)
00114 {
00115 return this->add(dpoint_type(slice, row, col));
00116 }
00117
00121 window3d() : super_type()
00122 {}
00123
00128 window3d(unsigned size) : super_type(size)
00129 {}
00130
00136 window3d(unsigned n, const coord crd[]) : super_type(n)
00137 {
00138 for (unsigned i = 0; i < 3 * n; i += 3)
00139 add(dpoint_type(crd[i], crd[i+1], crd[i+2]));
00140 }
00141
00143 static std::string
00144 name()
00145 {
00146 return std::string("window3d");
00147 }
00148
00149 protected:
00150
00159 coord
00160 delta_update_(const dpoint_type& dp)
00161 {
00162 delta_(abs(dp.slice()));
00163 delta_(abs(dp.row()));
00164 delta_(abs(dp.col()));
00165 return delta_;
00166 }
00167
00168 };
00169
00170
00171
00176 inline const window3d&
00177 win_c6_only()
00178 {
00179 static const coord crd[] = { -1, 0, 0,
00180 0, -1, 0,
00181 0, 0, -1,
00182 0, 0, 1,
00183 0, 1, 0,
00184 1, 0, 0};
00185 static const window3d win(6, crd);
00186 return win;
00187 }
00188
00195 inline const window3d&
00196 win_c6p()
00197 {
00198 static const coord crd[] = { -1, 0, 0,
00199 0, -1, 0,
00200 0, 0, -1,
00201 0, 0, 0,
00202 0, 0, 1,
00203 0, 1, 0,
00204 1, 0, 0};
00205 static const window3d win(7, crd);
00206 return win;
00207 }
00208
00213 inline const window3d&
00214 win_c18_only()
00215 {
00216 static const coord crd[] = { -1, -1, 0,
00217 -1, 0, -1,
00218 -1, 0, 0,
00219 -1, 0, 1,
00220 -1, 1, 0,
00221 0, -1, -1,
00222 0, -1, 0,
00223 0, -1, 1,
00224 0, 0, -1,
00225 0, 0, 1,
00226 0, 1, -1,
00227 0, 1, 0,
00228 0, 1, 1,
00229 1, -1, 0,
00230 1, 0, -1,
00231 1, 0, 0,
00232 1, 0, 1,
00233 1, 1, 0 };
00234 static window3d win(18, crd);
00235 return win;
00236 }
00237
00244 inline const window3d&
00245 win_c18p()
00246 {
00247 static const coord crd[] = { -1, -1, 0,
00248 -1, 0, -1,
00249 -1, 0, 0,
00250 -1, 0, 1,
00251 -1, 1, 0,
00252 0, -1, -1,
00253 0, -1, 0,
00254 0, -1, 1,
00255 0, 0, -1,
00256 0, 0, 0,
00257 0, 0, 1,
00258 0, 1, -1,
00259 0, 1, 0,
00260 0, 1, 1,
00261 1, -1, 0,
00262 1, 0, -1,
00263 1, 0, 0,
00264 1, 0, 1,
00265 1, 1, 0 };
00266 static window3d win(19, crd);
00267 return win;
00268 }
00269
00274 inline const window3d&
00275 win_c26_only()
00276 {
00277 static const coord crd[] = { -1, -1, -1,
00278 -1, -1, 0,
00279 -1, -1, 1,
00280 -1, 0, -1,
00281 -1, 0, 0,
00282 -1, 0, 1,
00283 -1, 1, -1,
00284 -1, 1, 0,
00285 -1, 1, 1,
00286 0, -1, -1,
00287 0, -1, 0,
00288 0, -1, 1,
00289 0, 0, -1,
00290 0, 0, 1,
00291 0, 1, -1,
00292 0, 1, 0,
00293 0, 1, 1,
00294 1, -1, -1,
00295 1, -1, 0,
00296 1, -1, 1,
00297 1, 0, -1,
00298 1, 0, 0,
00299 1, 0, 1,
00300 1, 1, -1,
00301 1, 1, 0,
00302 1, 1, 1 };
00303 static window3d win(26, crd);
00304 return win;
00305 }
00306
00313 inline const window3d&
00314 win_c26p()
00315 {
00316 static const coord crd[] = { -1, -1, -1,
00317 -1, -1, 0,
00318 -1, -1, 1,
00319 -1, 0, -1,
00320 -1, 0, 0,
00321 -1, 0, 1,
00322 -1, 1, -1,
00323 -1, 1, 0,
00324 -1, 1, 1,
00325 0, -1, -1,
00326 0, -1, 0,
00327 0, -1, 1,
00328 0, 0, -1,
00329 0, 0, 0,
00330 0, 0, 1,
00331 0, 1, -1,
00332 0, 1, 0,
00333 0, 1, 1,
00334 1, -1, -1,
00335 1, -1, 0,
00336 1, -1, 1,
00337 1, 0, -1,
00338 1, 0, 0,
00339 1, 0, 1,
00340 1, 1, -1,
00341 1, 1, 0,
00342 1, 1, 1 };
00343 static window3d win(27, crd);
00344 return win;
00345 }
00346
00347
00348
00362 inline window3d
00363 mk_win_block(unsigned nslices, unsigned nrows, unsigned ncols)
00364 {
00365 precondition(nslices >= 3 && (nslices % 2) == 1);
00366 precondition(nrows >= 3 && (nrows % 2) == 1);
00367 precondition(ncols >= 3 && (ncols % 2) == 1);
00368 window3d win(nrows * ncols);
00369 int half_nslices = nslices / 2;
00370 int half_nrows = nrows / 2;
00371 int half_ncols = ncols / 2;
00372 for (coord slice = - half_nslices; slice <= half_nslices; ++slice)
00373 for (coord row = - half_nrows; row <= half_nrows; ++row)
00374 for (coord col = - half_ncols; col <= half_ncols; ++col)
00375 win.add(slice, row, col);
00376 return win;
00377 }
00378
00391 inline window3d
00392 mk_win_ellipsoid(float zradius, float yradius, float xradius)
00393 {
00394 precondition(zradius > 0);
00395 precondition(yradius > 0);
00396 precondition(xradius > 0);
00397
00398 window3d win;
00399 coord zmax = (coord)roundf(zradius);
00400 float zr2 = zradius * zradius;
00401 float yr2 = yradius * yradius;
00402 for (coord z = -zmax; z <= zmax; ++z)
00403 {
00404
00405
00406
00407
00408
00409
00410
00411 float v = 1 - z * z / zr2;
00412 if (v < 0) v = 0;
00413 coord ymax = (coord)roundf(yradius * sqrtf(v));
00414 for (coord y = -ymax; y <= ymax; ++y)
00415 {
00416 float w = v - y * y / yr2;
00417 if (w < 0) w = 0;
00418 coord xmax = (coord)roundf(xradius * sqrtf(w));
00419 for (coord x = -xmax; x <= xmax; ++x)
00420 win.add(z, y, x);
00421 }
00422 }
00423 return win;
00424 }
00425
00431 inline window3d
00432 mk_win_cube(unsigned width)
00433 {
00434 return mk_win_block(width, width, width);
00435 }
00436
00442 inline window3d
00443 mk_win_ball(float radius)
00444 {
00445 return mk_win_ellipsoid(radius, radius, radius);
00446 }
00447
00448 }
00449
00450 #endif // OLENA_CORE_WINDOW3D_HH