window3d.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_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; // forward declaration
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   // std win
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   // mk_win's
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               x^2         y^2         z^2
00406            --------- + --------- + --------- = 1
00407            xradius^2   yradius^2   zradius^2
00408         */
00409 
00410         /* Set x to 0 in the above formula to find ymax.  */
00411         float v = 1 - z * z / zr2;
00412         if (v < 0) v = 0;       // Can happen because zmax has been rounded.
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;   // Can happen because ymax has been rounded.
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 } // end of oln
00449 
00450 #endif // OLENA_CORE_WINDOW3D_HH

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