[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

vigra/voxelneighborhood.hxx

00001 /************************************************************************/
00002 /*                                                                      */
00003 /*     Copyright 2006-2007 by F. Heinrich, B. Seppke, Ullrich Koethe    */
00004 /*       Cognitive Systems Group, University of Hamburg, Germany        */
00005 /*                                                                      */
00006 /*    This file is part of the VIGRA computer vision library.           */
00007 /*    The VIGRA Website is                                              */
00008 /*        http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/      */
00009 /*    Please direct questions, bug reports, and contributions to        */
00010 /*        ullrich.koethe@iwr.uni-heidelberg.de    or                    */
00011 /*        vigra@informatik.uni-hamburg.de                               */
00012 /*                                                                      */
00013 /*    Permission is hereby granted, free of charge, to any person       */
00014 /*    obtaining a copy of this software and associated documentation    */
00015 /*    files (the "Software"), to deal in the Software without           */
00016 /*    restriction, including without limitation the rights to use,      */
00017 /*    copy, modify, merge, publish, distribute, sublicense, and/or      */
00018 /*    sell copies of the Software, and to permit persons to whom the    */
00019 /*    Software is furnished to do so, subject to the following          */
00020 /*    conditions:                                                       */
00021 /*                                                                      */
00022 /*    The above copyright notice and this permission notice shall be    */
00023 /*    included in all copies or substantial portions of the             */
00024 /*    Software.                                                         */
00025 /*                                                                      */
00026 /*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND    */
00027 /*    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES   */
00028 /*    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND          */
00029 /*    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT       */
00030 /*    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,      */
00031 /*    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING      */
00032 /*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR     */
00033 /*    OTHER DEALINGS IN THE SOFTWARE.                                   */                
00034 /*                                                                      */
00035 /************************************************************************/
00036 
00037 #ifndef VIGRA_VOXELNEIGHBORHOOD_HXX
00038 #define VIGRA_VOXELNEIGHBORHOOD_HXX
00039 
00040 #include "tinyvector.hxx"
00041 #include "pixelneighborhood.hxx"
00042 
00043 namespace vigra {
00044     
00045 /** \addtogroup VoxelNeighborhood Utilities to manage voxel neighborhoods
00046 
00047     6- and 26-neighborhood definitions and circulators.
00048 
00049     <b>\#include</b> <<a href="voxelneighborhood_8hxx-source.html">vigra/voxelneighborhood.hxx</a>><br>
00050 
00051     <b>See also:</b> \ref vigra::NeighborhoodCirculator
00052  */
00053 //@{
00054 
00055     /// 3-dimensional difference vector
00056     typedef vigra::TinyVector<int, 3> Diff3D;
00057    
00058 /********************************************************/
00059 /*                                                      */
00060 /*                      AtVolumeBorder                  */
00061 /*                                                      */
00062 /********************************************************/
00063 
00064 /** \brief Encode whether a voxel is near the volume border.
00065 
00066         //    This enum is used with \ref isAtVolumeBorder() and 
00067         //    \ref vigra::RestrictedNeighborhoodCirculator.
00068 
00069         //<b>\#include</b> <<a href="voxelneighborhood_8hxx-source.html">vigra/voxelneighborhood.hxx</a>><br>
00070         //Namespace: vigra
00071 */
00072 
00073 typedef AtImageBorder AtVolumeBorder;
00074 
00075 
00076 /** \brief Find out whether a voxel is at the volume border.
00077 
00078     This function checks if \a x == 0 or \a x == \a width - 1 and 
00079     \a y == 0 or \a y == \a height - 1 and so on and returns the appropriate value
00080     of \ref vigra::AtVolumeBorder, or zero when the voxel is not at te volume border.
00081     The behavior of the function is undefined if (x,y,z) is not inside the volume.
00082 */
00083 inline AtVolumeBorder isAtVolumeBorder(int x, int y, int z, int width, int height, int depth)
00084 {
00085     return static_cast<AtVolumeBorder>((x == 0 
00086                                          ? LeftBorder
00087                                          : x == width-1
00088                                              ? RightBorder
00089                                              : NotAtBorder) |
00090                                        (y == 0 
00091                                          ? TopBorder
00092                                          : y == height-1
00093                                              ? BottomBorder
00094                                              : NotAtBorder) |
00095                                        (z == 0 
00096                                          ? FrontBorder
00097                                          : z == depth-1
00098                                              ? RearBorder
00099                                              : NotAtBorder));
00100 };
00101 /** \brief Find out whether a voxel is at a scan-order relevant volume border.
00102     This function checks if \a x == 0 or \a y == 0 or \a z == \a 0 and returns the 
00103         appropriate value of \ref vigra::AtVolumeBorder, or zero when the voxel is
00104         not at te volume border.
00105     The behavior of the function is undefined if (x,y,z) is not inside the volume.
00106 */
00107 inline AtVolumeBorder isAtVolumeBorderCausal(int x, int y, int z, int width, int height, int depth)
00108 {
00109     return static_cast<AtVolumeBorder>((x == 0 
00110                                          ? LeftBorder
00111                                          : NotAtBorder) |
00112                                        (y == 0 
00113                                          ? TopBorder
00114                                          : NotAtBorder) |
00115                                        (z == 0 
00116                                          ? FrontBorder
00117                                          : NotAtBorder));
00118 };
00119 /** TODO: Write new comment \brief Find out whether a voxel is at a scan-order relevant volume border.
00120     This function checks if \a x == 0 or \a y == 0 or \a z == \a 0 and returns the 
00121         appropriate value of \ref vigra::AtVolumeBorder, or zero when the voxel is
00122         not at te volume border.
00123     The behavior of the function is undefined if (x,y,z) is not inside the volume.
00124 */
00125 inline AtVolumeBorder isAtVolumeBorderAntiCausal(int x, int y, int z, int width, int height, int depth)
00126 {
00127     return static_cast<AtVolumeBorder>((x == width-1 
00128                                          ? RightBorder
00129                                          : NotAtBorder) |
00130                                        (y == height-1 
00131                                          ? BottomBorder
00132                                          : NotAtBorder) |
00133                                        (z == depth-1 
00134                                          ? RearBorder
00135                                          : NotAtBorder));
00136 };
00137 
00138 /********************************************************/
00139 /*                                                      */
00140 /*                   Neighborhood3DSix                  */
00141 /*                                                      */
00142 /********************************************************/
00143 
00144 /** 3D 6-Neighborhood. */
00145 namespace Neighborhood3DSix
00146 {
00147 
00148 /** \brief Encapsulation of direction management of neighbors for a 3D 6-neighborhood.
00149 */
00150 class NeighborCode3D
00151 {
00152     public:
00153     
00154     typedef Diff3D difference_type;
00155     
00156     /** provides enumeration of all directions.
00157         DirectionCount may be used for portable loop termination conditions.
00158     */
00159     enum Direction {
00160         Error = -1,    
00161         InFront= 0,         
00162         North,          
00163         West ,      
00164         Behind,
00165         South,
00166         East,         
00167         DirectionCount,
00168         CausalFirst = InFront,
00169         CausalLast  = West,
00170         AntiCausalFirst = Behind,
00171         AntiCausalLast  = East,
00172 
00173         InitialDirection = InFront,
00174         OppositeDirPrefix = 1,
00175         OppositeOffset = 3
00176     };
00177 
00178     static unsigned int directionBit(Direction d) 
00179     {
00180         static unsigned int b[] = { 1 << (InFront + 1),
00181                                     1 << (North + 1), 
00182                                     1 << (West + 1), 
00183                                     1 << (Behind + 1),
00184                                     1 << (South + 1), 
00185                                     1 << (East + 1)
00186                                   };
00187         return b[d];
00188     };
00189 
00190 
00191     /** The number of valid neighbors if the current center is at the volume border.
00192     */
00193     static unsigned int nearBorderDirectionCount(AtVolumeBorder b)
00194     {
00195         static unsigned int c[] = { 6, 5, 5, 0, 5, 4, 4, 0, 5, 4, 
00196                                     4, 0, 0, 0, 0, 0, 5, 4, 4, 0,
00197                                     4, 3, 3, 0, 4, 3, 3, 0, 0, 0,
00198                                     0, 0, 5, 4, 4, 0, 4, 3, 3, 0,
00199                                     4, 3, 3};
00200         return c[b];
00201     }
00202     
00203     /** The valid direction codes when the center is at the volume border.
00204         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
00205     */
00206     static Direction nearBorderDirections(AtVolumeBorder b, int index)
00207     {
00208         static Direction c[43][6] = {
00209                 { InFront, North, West, Behind, South, East},   // 0 - NotAtBorder
00210                 { InFront, North, West, Behind, South, Error},  // 1 - AtRightBorder
00211                 { InFront, North, Behind, South, East, Error},  // 2 - AtLeftBorder
00212                 { Error, Error, Error, Error, Error, Error},    
00213                 { InFront, West, Behind, South, East, Error},   // 4 - AtTopBorder    
00214                 { InFront, West, Behind, South, Error, Error},  // 5 - AtTopRightBorder
00215                 { InFront, Behind, South, East, Error, Error},  // 6 - AtTopLeftBorder
00216                 { Error, Error, Error, Error, Error, Error},    
00217                 { InFront, North, West, Behind, East, Error},   // 8 - AtBottomBorder
00218                 { InFront, North, West, Behind, Error, Error},  // 9 - AtBottomRightBorder
00219                 { InFront, North, Behind, East, Error, Error},  //10- AtBottomLeftBorder
00220                 { Error, Error, Error, Error, Error, Error},    
00221                 { Error, Error, Error, Error, Error, Error},    
00222                 { Error, Error, Error, Error, Error, Error},    
00223                 { Error, Error, Error, Error, Error, Error},    
00224                 { Error, Error, Error, Error, Error, Error},    
00225                 { North, West, Behind, South, East, Error},     //16 - AtFrontBorder
00226                 { North, West, Behind, South, Error, Error},    //17 - AtFrontRightBorder
00227                 { North, Behind, South, East, Error, Error},    //18 - AtFrontLeftBorder
00228                 { Error, Error, Error, Error, Error, Error},    
00229                 { West, Behind, South, East, Error,  Error},    //20 - AtTopFrontBorder
00230                 { West, Behind, South, Error, Error, Error},    //21 - AtTopRightFrontBorder
00231                 { Behind, South, East, Error, Error,  Error},   //22 - AtTopLeftFrontBorder
00232                 { Error, Error, Error, Error, Error, Error},    
00233                 { North, West, Behind, East, Error, Error},     //24 - AtBottomFrontBorder
00234                 { North, West, Behind, Error, Error, Error},    //25 - AtBottomRightFrontBorder
00235                 { North, Behind, East, Error, Error, Error},    //26 - AtBottomLeftFrontBorder
00236                 { Error, Error, Error, Error, Error, Error},    
00237                 { Error, Error, Error, Error, Error, Error},    
00238                 { Error, Error, Error, Error, Error, Error},    
00239                 { Error, Error, Error, Error, Error, Error},    
00240                 { Error, Error, Error, Error, Error, Error},    
00241                 { InFront, North, West, South, East,Error},     //32 - AtRearBorder
00242                 { InFront, North, West, South, Error, Error},   //33 - AtRearRightBorder
00243                 { InFront, North, South, East, Error, Error},   //34 - AtRearLeftBorder
00244                 { Error, Error, Error, Error, Error, Error},    
00245                 { InFront, West, South, East, Error, Error},    //36 - AtTopRearBorder    
00246                 { InFront, West, South, Error, Error, Error},   //37 - AtTopRightRearBorder    
00247                 { InFront, South, East, Error, Error, Error},   //38 - AtTopLeftRearBorder
00248                 { Error, Error, Error, Error, Error, Error},    
00249                 { InFront, North, West, East, Error, Error},    //40 - AtBottomRearBorder
00250                 { InFront, North, West, Error, Error, Error},   //41 - AtBottomRightRearBorder
00251                 { InFront, North, East, Error, Error, Error}    //42 - AtBottomLeftRearBorder
00252                };
00253         return c[b][index];
00254     }
00255         
00256     /** The valid direction three codes in anti causal direction (means: look back in scanline
00257         direction)when the center is at the volume border.
00258         Should be used with isAtVolumeBorderCausal to determine the Directions, as this
00259         avoids using of the nonesense border ids (e.g. 0,1,8,9...) of this table.
00260         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
00261     */
00262     static Direction nearBorderDirectionsCausal(AtVolumeBorder b, int index)
00263     {
00264         static Direction c[43][3] = {
00265             { InFront, North, West},                    // 0 - NotAtBorder -----> should never be used
00266             { InFront, North, West},                    // 1 - AtRightBorder -----> should never be used
00267             { InFront, North, Error},                   // 2 - AtLeftBorder
00268             { Error, Error, Error},    
00269             { InFront, West, Error},                    // 4 - AtTopBorder    
00270             { InFront, West, Error},                    // 5 - AtTopRightBorder
00271             { InFront, Error,Error},                    // 6 - AtTopLeftBorder
00272             { Error, Error, Error},    
00273             { InFront, North, West},                    // 8 - AtBottomBorder -----> should never be used
00274             { InFront, North, West},                    // 9 - AtBottomRightBorder -----> should never be used
00275             { InFront, North, Error},                   //10- AtBottomLeftBorder
00276             { Error, Error, Error},    
00277             { Error, Error, Error},    
00278             { Error, Error, Error},    
00279             { Error, Error, Error},    
00280             { Error, Error, Error},    
00281             { North, West, Error},                      //16 - AtFrontBorder
00282             { North, West, Error},                      //17 - AtFrontRightBorder
00283             { North, Error, Error},                     //18 - AtFrontLeftBorder
00284             { Error, Error, Error},    
00285             { West, Error, Error},                      //20 - AtTopFrontBorder
00286             { West, Error, Error},                      //21 - AtTopRightFrontBorder
00287             { Error, Error,  Error},                    //22 - AtTopLeftFrontBorder
00288             { Error, Error, Error},    
00289             { North, West, Error},                      //24 - AtBottomFrontBorder
00290             { North, West, Error},                      //25 - AtBottomRightFrontBorder
00291             { North, Error, Error},                     //26 - AtBottomLeftFrontBorder
00292             { Error, Error, Error},    
00293             { Error, Error, Error},    
00294             { Error, Error, Error},    
00295             { Error, Error, Error},    
00296             { Error, Error, Error},                      
00297             { InFront, North, West},                    //32 - AtRearBorder -----> should never be used
00298             { InFront, North, West},                    //33 - AtRearRightBorder -----> should never be used
00299             { InFront, North, Error},                   //34 - AtRearLeftBorder
00300             { Error, Error, Error},    
00301             { InFront, West, Error},                    //36 - AtTopRearBorder    
00302             { InFront, West, Error},                    //37 - AtTopRightRearBorder    
00303             { InFront, Error, Error},                   //38 - AtTopLeftRearBorder
00304             { Error, Error, Error},    
00305             { InFront, North, West},                    //40 - AtBottomRearBorder -----> should never be used
00306             { InFront, North, West},                    //41 - AtBottomRightRearBorder -----> should never be used
00307             { InFront, North, Error}                    //42 - AtBottomLeftRearBorder
00308         };
00309         return c[b][index];
00310     }
00311     
00312     /** transform direction code into corresponding Diff3D offset.
00313         (note: there is no bounds checking on the code you pass.)
00314     */
00315     static Diff3D const & diff(Direction code)
00316     {
00317         static Diff3D d[] = {
00318                     Diff3D(  0,  0, -1),  //InFront
00319                     Diff3D(  0, -1,  0),  //North
00320                     Diff3D( -1,  0,  0),  //West
00321                     Diff3D(  0,  0,  1),  //Behind
00322                     Diff3D(  0,  1,  0),  //South
00323                     Diff3D(  1,  0,  0)   //East
00324                 };
00325         return d[code];
00326     }
00327 
00328     /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
00329         (note: there is no bounds checking on the code you pass.)
00330     */
00331     static Diff3D const & diff(int code) { return diff(static_cast<Direction>(code)); }
00332 
00333     /**  Equivalent to <tt>diff(code)[dim]</tt> */
00334     static int diff(Direction code, int dim) { return diff(code)[dim]; }
00335    
00336     /** Get the relative offset from one neighbor to the other.
00337         For example, <tt>relativeDiff(East, West) == multi_differencetype(-2,0,0)</tt>.
00338         (note: there is no bounds checking on the code you pass.)
00339     */
00340     static Diff3D const & relativeDiff(Direction fromCode, Direction toCode)
00341     {
00342       static Diff3D d[6][6] = 
00343           {    
00344                 //     InFront      -      North         -           West     -         Behind     -      South        -        East       
00345                 { Diff3D( 0, 0, 0), Diff3D(0, -1, 1), Diff3D(-1, 0, 1), Diff3D( 0, 0, 2), Diff3D( 0, 1, 1),  Diff3D( 1, 0, 1)}, //InFront
00346                 { Diff3D( 0, 1,-1), Diff3D( 0, 0, 0), Diff3D(-1, 1, 0), Diff3D( 0, 1, 1), Diff3D( 0, 2, 0),  Diff3D( 1, 1, 0)}, //North
00347                 { Diff3D( 1, 0,-1), Diff3D( 1,-1, 0), Diff3D( 0, 0, 0), Diff3D( 1, 0, 1), Diff3D( 1, 1, 0),  Diff3D( 2, 0, 0)}, //West
00348                 { Diff3D( 0, 0,-2), Diff3D( 0,-1,-1), Diff3D(-1, 0,-1), Diff3D( 0, 0, 0), Diff3D( 0, 1,-1),  Diff3D( 1, 0,-1)}, //Behind
00349                 { Diff3D( 0,-1,-1), Diff3D( 0,-2, 0), Diff3D(-1,-1, 0), Diff3D( 0,-1, 1), Diff3D( 0, 0, 0),  Diff3D( 1,-1, 0)}, //South
00350                 { Diff3D(-1, 0,-1), Diff3D(-1,-1, 0), Diff3D(-2, 0, 0), Diff3D(-1, 0, 1), Diff3D(-1, 1, 0), Diff3D( 0, 0, 0) }  //East
00351           };
00352 
00353         return d[fromCode][toCode];
00354     }
00355 
00356     /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
00357         (note: there is no bounds checking on the code you pass.)
00358     */
00359     static Diff3D const & relativeDiff(int fromCode, int toCode)
00360     {
00361         return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
00362     }
00363 
00364     /**  X-component of diff() */
00365     static int dX(Direction code) { return diff(code)[0]; }
00366     /**  Y-component of diff() */
00367     static int dY(Direction code) { return diff(code)[1]; }
00368     /**  Z-component of diff() */
00369     static int dZ(Direction code) { return diff(code)[2]; }
00370     
00371     /**  X-component of diff() */
00372     static int dX(int code) { return diff(code)[0]; }
00373     /**  Y-component of diff() */
00374     static int dY(int code) { return diff(code)[1]; }
00375     /**  Z-component of diff() */
00376     static int dZ(int code) { return diff(code)[2]; }
00377     
00378 
00379     /** transform Diff3D offset into corresponding direction code.
00380         The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
00381         is not in the 3DSix-Neighborhood.
00382     */
00383     static Direction code(Diff3D const & diff)
00384     {
00385         switch(diff[0]) {
00386             case  0:
00387             {
00388                 switch(diff[1]) {
00389                     case 0:
00390                         switch(diff[2]) {
00391                             case 1:
00392                                 return Behind;
00393                             case -1:
00394                                 return InFront;
00395                             default:
00396                                 return Error;
00397                         }
00398                                 
00399                     case 1:
00400                         return (diff[2] == 0) ? South : Error;
00401                     case -1:
00402                         return (diff[2] == 0) ? North : Error;
00403                     default:
00404                         return Error;
00405                 }
00406         }
00407         case -1:
00408             return ((diff[1] == 0) && (diff[2] == 0)) ? West : Error;
00409         case  1:
00410             return ((diff[1] == 0) && (diff[2] == 0)) ? East : Error;
00411         }
00412         return Error;
00413     }
00414   
00415     /** Check whether a code refers to a diagonal direction.
00416         Useful if you want to abstract the differences between 6- and 26-neighborhood.
00417         Always <tt>false</tt> for 6-neighborhood.
00418     */
00419     static bool isDiagonal(Direction) { return false; }
00420 
00421     static Diff3D const & right()           { return diff(East); }          /**<  Offset to the right neighbor */
00422     static Diff3D const & top()             { return diff(North); }         /**<  Offset to the top neighbor */
00423     static Diff3D const & left()            { return diff(West); }          /**<  Offset to the left neighbor */
00424     static Diff3D const & bottom()          { return diff(South); }         /**<  Offset to the bottom neighbor */
00425     static Diff3D const & rear()            { return diff(Behind); }        /**<  Offset to the rear neighbor */
00426     static Diff3D const & front()           { return diff(InFront); }       /**<  Offset to the neighbor in front */
00427 
00428     static Diff3D const & east()            { return diff(East); }          /**<  Offset to the east neighbor */
00429     static Diff3D const & north()           { return diff(North); }         /**<  Offset to the north neighbor */
00430     static Diff3D const & west()            { return diff(West); }          /**<  Offset to the west neighbor */
00431     static Diff3D const & south()           { return diff(South); }         /**<  Offset to the south neighbor */
00432     static Diff3D const & behind()          { return diff(Behind); }        /**<  Offset to the rear neighbor */
00433     static Diff3D const & infront()         { return diff(InFront); }       /**<  Offset to the neighbor in front */
00434 
00435 }; // class Neighborhood3DSix
00436 
00437 
00438 /** Export NeighborCode3D::Direction into the scope of namespace Neighborhood3DSix.
00439 */
00440 typedef NeighborCode3D::Direction Direction;
00441 
00442 static const Direction East           = NeighborCode3D::East;               /**<  Export NeighborCode3D::East to namespace Neighborhood3DSix */
00443 static const Direction North          = NeighborCode3D::North;              /**<  Export NeighborCode3D::North to namespace Neighborhood3DSix */
00444 static const Direction West           = NeighborCode3D::West;               /**<  Export NeighborCode3D::West to namespace Neighborhood3DSix */
00445 static const Direction South          = NeighborCode3D::South;              /**<  Export NeighborCode3D::South to namespace Neighborhood3DSix */
00446 static const Direction Behind         = NeighborCode3D::Behind;             /**<  Export NeighborCode3D::Behind to namespace Neighborhood3DSix */
00447 static const Direction InFront        = NeighborCode3D::InFront;            /**<  Export NeighborCode3D::InFront to namespace Neighborhood3DSix */
00448 static const Direction DirectionCount = NeighborCode3D::DirectionCount;     /**<  Export NeighborCode3D::DirectionCount to namespace Neighborhood3DSix */
00449 
00450 
00451 }//namespace Neighborhood3DSix
00452     
00453 /** Export \ref vigra::Neighborhood3DSix::NeighborCode3D into the scope of namespace vigra.
00454 */
00455 typedef Neighborhood3DSix::NeighborCode3D NeighborCode3DSix;
00456 
00457 /********************************************************/
00458 /*                                                      */
00459 /*                   Neighborhood3DTwentySix            */
00460 /*                                                      */
00461 /********************************************************/
00462 /** 3D 26-Neighborhood. */
00463 namespace Neighborhood3DTwentySix
00464 {
00465 
00466 /** \brief Encapsulation of direction management of neighbors for a 3D 26-neighborhood.
00467 */
00468 class NeighborCode3D
00469 {
00470     public:
00471 
00472     typedef Diff3D difference_type;
00473     
00474    /** provides enumeration of all directions.
00475        DirectionCount may be used for portable loop termination conditions.
00476      */
00477     enum Direction {
00478         Error = -1,
00479             InFrontNorthWest = 0,
00480             InFrontNorth,
00481             InFrontNorthEast,
00482             InFrontWest,
00483         InFront,
00484             InFrontEast,
00485             InFrontSouthWest,
00486             InFrontSouth,
00487             InFrontSouthEast,
00488         
00489             NorthWest,
00490             North,
00491             NorthEast,
00492         West,
00493             East,
00494             SouthWest,
00495             South,
00496             SouthEast,
00497 
00498             BehindNorthWest,
00499             BehindNorth,
00500             BehindNorthEast,
00501             BehindWest,
00502         Behind,
00503             BehindEast,
00504             BehindSouthWest,
00505             BehindSouth,
00506             BehindSouthEast,
00507 
00508         DirectionCount,
00509             CausalFirst = InFrontNorthWest,
00510             CausalLast  = West,
00511             AntiCausalFirst = BehindSouthEast,
00512             AntiCausalLast  = East,
00513 
00514             InitialDirection = InFrontNorthWest,
00515             OppositeDirPrefix = -1,
00516             OppositeOffset = 25
00517     };
00518 
00519     static unsigned int directionBit(Direction d) 
00520     {
00521         static unsigned int b[] = { 
00522                 1 <<    (InFrontNorthWest+1),
00523                 1 <<    (InFrontNorth+1),
00524                 1 <<  (InFrontNorthEast+1),
00525                 1 <<  (InFrontWest+1),
00526                 1 <<  (InFront+1),
00527                 1 <<  (InFrontEast+1),
00528                 1 <<  (InFrontSouthWest+1),
00529                 1 <<  (InFrontSouth+1),
00530                 1 <<  (InFrontSouthEast+1),
00531 
00532                 1 <<  (NorthWest+1),
00533                 1 <<  (North+1),
00534                 1 <<  (NorthEast+1),
00535                 1 <<  (West+1),
00536                 1 <<  (East+1),
00537                 1 <<  (SouthWest+1),
00538                 1 <<  (South+1),
00539                 1 <<  (SouthEast+1),
00540 
00541                 1 <<  (BehindNorthWest+1),
00542                 1 <<  (BehindNorth+1),
00543                 1 <<  (BehindNorthEast+1),
00544                 1 <<  (BehindWest+1),
00545                 1 <<  (Behind+1),
00546                 1 <<  (BehindEast+1),
00547                 1 <<  (BehindSouthWest+1),
00548                 1 <<  (BehindSouth+1),
00549                 1 <<  (BehindSouthEast+1)
00550             };
00551         return b[d];
00552     };
00553 
00554 
00555     /** The number of valid neighbors if the current center is at the volume border.
00556     */
00557     static unsigned int nearBorderDirectionCount(AtVolumeBorder b)
00558     {
00559         static unsigned int c[] = { 26, 17, 17,  0, 17, 11, 11,  0, 17, 11, 
00560                                     11,  0,  0,  0,  0,  0, 17, 11, 11,  0,
00561                                     11,  7,  7,  0, 11,  7,  7,  0,  0,  0,
00562                                      0,  0, 17, 11, 11,  0, 11,  7,  7,  0,
00563                                     11,  7,  7};
00564         return c[b];
00565     }
00566     
00567     /** The valid direction codes when the center is at the volume border.
00568         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
00569     */
00570     static Direction nearBorderDirections(AtVolumeBorder b, int index)
00571     {
00572         static Direction c[43][26] = {
00573                    //0 - NotAtBorder
00574                    {    InFrontNorthWest,   InFrontNorth,   InFrontNorthEast,
00575                         InFrontWest,        InFront,        InFrontEast,
00576                         InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,
00577       
00578                         NorthWest, North, NorthEast,
00579                         West,             East,
00580                         SouthWest, South, SouthEast, 
00581 
00582                         BehindNorthWest, BehindNorth, BehindNorthEast,
00583                         BehindWest,      Behind,      BehindEast,
00584                         BehindSouthWest, BehindSouth, BehindSouthEast},    
00585                     //1 - AtRightBorder
00586                     {   InFrontNorthWest, InFrontNorth, /*InFrontNorthEast,*/
00587                         InFrontWest,      InFront,      /*InFrontEast,*/
00588                         InFrontSouthWest, InFrontSouth, /*InFrontSouthEast,*/
00589       
00590                         NorthWest, North, /*NorthEast,*/
00591                         West,             /*East,*/
00592                         SouthWest, South, /*SouthEast,*/ 
00593 
00594                         BehindNorthWest, BehindNorth, /*BehindNorthEast,*/
00595                         BehindWest,      Behind,      /*BehindEast,*/
00596                         BehindSouthWest, BehindSouth, /*BehindSouthEast,*/ 
00597                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00598                     //2 - AtLeftBorder
00599                     {   /*InFrontNorthWest,*/   InFrontNorth, InFrontNorthEast,
00600                         /*InFrontWest,*/       InFront,      InFrontEast,
00601                         /*InFrontSouthWest,*/   InFrontSouth, InFrontSouthEast,
00602                   
00603                         /*NorthWest,*/ North, NorthEast,
00604                         /*West,*/            East,
00605                         /*SouthWest,*/ South, SouthEast, 
00606 
00607                         /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
00608                         /*BehindWest,*/     Behind,      BehindEast,
00609                         /*BehindSouthWest,*/ BehindSouth, BehindSouthEast, 
00610                         Error, Error, Error, Error, Error, Error, Error, Error, Error},
00611                     //3 - Nothin'
00612                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00613                         Error, Error, Error, Error,        Error, Error, Error, Error, 
00614                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00615                     //4 - AtTopBorder    
00616                     {   /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,*/
00617                         InFrontWest,        InFront,      InFrontEast,
00618                         InFrontSouthWest, InFrontSouth,   InFrontSouthEast,
00619                   
00620                         /*NorthWest, North, NorthEast,*/
00621                         West,             East,
00622                         SouthWest, South, SouthEast, 
00623 
00624                         /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
00625                         BehindWest,                 Behind,                 BehindEast,
00626                         BehindSouthWest, BehindSouth, BehindSouthEast, 
00627                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00628                     //5 - AtTopRightBorder
00629                     {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
00630                         InFrontWest,        InFront,        /*InFrontEast,*/
00631                         InFrontSouthWest, InFrontSouth,     /*InFrontSouthEast,*/
00632       
00633                         /*NorthWest, North, NorthEast,*/
00634                         West,             /*East,*/
00635                         SouthWest, South, /*SouthEast,*/ 
00636 
00637                         /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
00638                         BehindWest,        Behind,      /*BehindEast,*/
00639                         BehindSouthWest, BehindSouth,   /*BehindSouthEast,*/ 
00640                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00641                         Error, Error, Error, Error, Error, Error},    
00642                     //6 - AtTopLeftBorder
00643                     {   /*InFrontNorthWest,     InFrontNorth,   InFrontNorthEast,*/
00644                         /*InFrontWest,*/        InFront,        InFrontEast,
00645                         /*InFrontSouthWest,*/   InFrontSouth,   InFrontSouthEast,
00646        
00647                         /*NorthWest,    North,  NorthEast,*/
00648                         /*West,*/               East,
00649                         /*SouthWest,*/  South,  SouthEast, 
00650 
00651                         /*BehindNorthWest,      BehindNorth, BehindNorthEast,*/
00652                         /*BehindWest, */        Behind,      BehindEast,
00653                         /*BehindSouthWest,*/    BehindSouth, BehindSouthEast, 
00654                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00655                         Error, Error, Error, Error, Error, Error},
00656                     //7 - Nothin'
00657                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00658                         Error, Error, Error, Error, Error, Error, Error, Error, 
00659                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00660                     //8 - AtBottomBorder
00661                     {   InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
00662                         InFrontWest,      InFront,         InFrontEast,
00663                         /*InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
00664                   
00665                         NorthWest,      North,  NorthEast,
00666                         West,                   East,
00667                         /*SouthWest,    South,  SouthEast,*/
00668 
00669                         BehindNorthWest,    BehindNorth, BehindNorthEast,
00670                         BehindWest,         Behind,      BehindEast,
00671                         /*BehindSouthWest,  BehindSouth, BehindSouthEast*/ 
00672                         Error, Error, Error, Error, Error, Error, Error, Error, Error},                    
00673                     //9 - AtBottomRightBorder
00674                     {   InFrontNorthWest, InFrontNorth,    /*InFrontNorthEast,*/
00675                         InFrontWest,      InFront,         /*InFrontEast,*/
00676                         /*InFrontSouthWest, InFrontSouth,  InFrontSouthEast,*/
00677       
00678                         NorthWest, North,   /*NorthEast,*/
00679                         West,               /*East,*/
00680                         /*SouthWest, South, SouthEast,*/
00681 
00682                         BehindNorthWest, BehindNorth,   /*BehindNorthEast,*/
00683                         BehindWest,      Behind,        /*BehindEast,*/
00684                         /*BehindSouthWest, BehindSouth, BehindSouthEast*/ 
00685                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00686                         Error, Error, Error, Error, Error, Error},        
00687                     //10 - AtBottomLeftBorder
00688                     {   /*InFrontNorthWest,*/   InFrontNorth,   InFrontNorthEast,
00689                         /*InFrontWest,*/        InFront,        InFrontEast,
00690                         /*InFrontSouthWest,     InFrontSouth,   InFrontSouthEast,*/
00691       
00692                         /*NorthWest,*/  North,  NorthEast,
00693                         /*West,*/               East,
00694                         /*SouthWest,    South,  SouthEast,*/
00695 
00696                         /*BehindNorthWest,*/ BehindNorth,   BehindNorthEast,
00697                         /*BehindWest,*/      Behind,        BehindEast,
00698                         /*BehindSouthWest, BehindSouth,     BehindSouthEast*/ 
00699                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00700                         Error, Error, Error, Error, Error, Error},
00701                     //11 - Nothin'
00702                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00703                         Error, Error, Error, Error, Error, Error, Error, Error, 
00704                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00705                     //12 - Nothin'
00706                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00707                         Error, Error, Error, Error, Error, Error, Error, Error, 
00708                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00709                     //13 - Nothin'
00710                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00711                         Error, Error, Error, Error, Error, Error, Error, Error, 
00712                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00713                     //14 - Nothin'
00714                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00715                         Error, Error, Error, Error, Error, Error, Error, Error, 
00716                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00717                     //15 - Nothin'
00718                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00719                         Error, Error, Error, Error, Error, Error, Error, Error, 
00720                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00721                     //16 - AtFrontBorder
00722                     {   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
00723                         InFrontWest,        InFront,         InFrontEast,
00724                         InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
00725       
00726                         NorthWest, North, NorthEast,
00727                         West,             East,
00728                         SouthWest, South, SouthEast, 
00729 
00730                         BehindNorthWest, BehindNorth, BehindNorthEast,
00731                         BehindWest,      Behind,      BehindEast,
00732                         BehindSouthWest, BehindSouth, BehindSouthEast, 
00733                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00734                     //17 - AtFrontRightBorder
00735                     {   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
00736                         InFrontWest,              InFront,                 InFrontEast,
00737                         InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
00738       
00739                         NorthWest, North, /*NorthEast,*/
00740                         West,             /*East,*/
00741                         SouthWest, South, /*SouthEast,*/ 
00742 
00743                         BehindNorthWest, BehindNorth, /*BehindNorthEast,*/
00744                         BehindWest,      Behind,      /*BehindEast,*/
00745                         BehindSouthWest, BehindSouth, /*BehindSouthEast,*/ 
00746                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00747                         Error, Error, Error, Error, Error, Error},    
00748                     //18 - AtFrontLeftBorder
00749                     {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
00750                         InFrontWest,        InFront,        InFrontEast,
00751                         InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
00752       
00753                         /*NorthWest,*/ North, NorthEast,
00754                         /*West,*/             East,
00755                         /*SouthWest,*/ South, SouthEast, 
00756 
00757                         /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
00758                         /*BehindWest,*/      Behind,      BehindEast,
00759                         /*BehindSouthWest,*/ BehindSouth, BehindSouthEast, 
00760                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00761                         Error, Error, Error, Error, Error, Error},    
00762                     //19 - Nothin'
00763                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00764                         Error, Error, Error, Error, Error, Error, Error, Error, 
00765                         Error, Error, Error, Error, Error, Error, Error, Error, Error},
00766                     //20 - AtTopFrontBorder
00767                     {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
00768                         InFrontWest,        InFront,        InFrontEast,
00769                         InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
00770       
00771                         /*NorthWest,    North,  NorthEast,*/
00772                         West,                   East,
00773                         SouthWest,      South,  SouthEast, 
00774 
00775                         /*BehindNorthWest,  BehindNorth,    BehindNorthEast,*/
00776                         BehindWest,         Behind,         BehindEast,
00777                         BehindSouthWest,    BehindSouth,    BehindSouthEast, 
00778                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00779                         Error, Error, Error, Error, Error, Error},    
00780                     //21 - AtTopRightFrontBorder
00781                     {   /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
00782                         InFrontWest,        InFront,       InFrontEast,
00783                         InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
00784       
00785                         /*NorthWest, North, NorthEast,*/
00786                         West,               /*East,*/
00787                         SouthWest,   South, /*SouthEast,*/ 
00788 
00789                         /*BehindNorthWest, BehindNorth, BehindNorthEast,*/
00790                         BehindWest,        Behind,      /*BehindEast,*/
00791                         BehindSouthWest, BehindSouth,   /*BehindSouthEast,*/ 
00792                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00793                         Error, Error, Error, Error, Error, Error,
00794                         Error, Error, Error, Error},    
00795                     //22 - AtTopLeftFrontBorder
00796                     {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,
00797                         InFrontWest,        InFront,        InFrontEast,
00798                         InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,*/
00799       
00800                         /*NorthWest,    North, NorthEast,*/
00801                         /*West,*/              East,
00802                         /*SouthWest,*/  South, SouthEast, 
00803 
00804                         /*BehindNorthWest,      BehindNorth, BehindNorthEast,*/
00805                         /*BehindWest,*/         Behind,      BehindEast,
00806                         /*BehindSouthWest,*/    BehindSouth, BehindSouthEast, 
00807                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00808                         Error, Error, Error, Error, Error, Error,
00809                         Error, Error, Error, Error},    
00810                     //23 - Nothin'
00811                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00812                         Error, Error, Error, Error, Error, Error, Error, Error, 
00813                         Error, Error, Error, Error, Error, Error, Error, Error, Error},
00814                     //24 - AtBottomFrontBorder
00815                     {   /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,
00816                         InFrontWest,        InFront,      InFrontEast,
00817                         InFrontSouthWest,   InFrontSouth, InFrontSouthEast,*/
00818       
00819                         NorthWest,      North, NorthEast,
00820                         West,                  East,
00821                         /*SouthWest,    South, SouthEast,*/
00822 
00823                         BehindNorthWest,    BehindNorth, BehindNorthEast,
00824                         BehindWest,         Behind,      BehindEast,
00825                         /*BehindSouthWest,  BehindSouth, BehindSouthEast*/ 
00826                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00827                         Error, Error, Error, Error, Error, Error},    
00828                     //25 - AtBottomRightFrontBorder
00829                     {   /*InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
00830                         InFrontWest,        InFront,         InFrontEast,
00831                         InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
00832       
00833                         NorthWest,      North,  /*NorthEast,*/
00834                         West,                   /* East,*/
00835                         /*SouthWest,    South,  SouthEast,*/
00836 
00837                         BehindNorthWest,    BehindNorth, /*BehindNorthEast,*/
00838                         BehindWest,         Behind,      /*BehindEast,*/
00839                         /*BehindSouthWest,  BehindSouth, BehindSouthEast*/ 
00840                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00841                         Error, Error, Error, Error, Error, Error,
00842                         Error, Error, Error, Error},    
00843                     //26 - AtBottomLeftFrontBorder
00844                     { /*InFrontNorthWest, InFrontNorth, InFrontNorthEast,
00845                         InFrontWest,      InFront,      InFrontEast,
00846                         InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
00847       
00848                         /*NorthWest,*/ North, NorthEast,
00849                         /*West,*/             East,
00850                         /*SouthWest,   South, SouthEast,*/
00851 
00852                         /*BehindNorthWest,*/ BehindNorth, BehindNorthEast,
00853                         /*BehindWest,*/      Behind,      BehindEast,
00854                         /*BehindSouthWest,   BehindSouth, BehindSouthEast*/ 
00855                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00856                         Error, Error, Error, Error, Error, Error,
00857                         Error, Error, Error, Error},    
00858                     //27 - Nothin'
00859                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00860                         Error, Error, Error, Error, Error, Error, Error, Error, 
00861                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00862                     //28 - Nothin'
00863                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00864                         Error, Error, Error, Error, Error, Error, Error, Error, 
00865                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00866                     //29 - Nothin'
00867                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00868                         Error, Error, Error, Error, Error, Error, Error, Error, 
00869                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00870                     //30 - Nothin'
00871                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00872                         Error, Error, Error, Error, Error, Error, Error, Error, 
00873                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00874                     //31 - Nothin'
00875                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00876                         Error, Error, Error, Error, Error, Error, Error, Error, 
00877                         Error, Error, Error, Error, Error, Error, Error, Error, Error},
00878                     //32 - AtRearBorder
00879                     {   InFrontNorthWest, InFrontNorth, InFrontNorthEast,
00880                         InFrontWest,      InFront,      InFrontEast,
00881                         InFrontSouthWest, InFrontSouth, InFrontSouthEast,
00882       
00883                         NorthWest, North, NorthEast,
00884                         West,             East,
00885                         SouthWest, South, SouthEast, 
00886 
00887                         /*BehindNorthWest, BehindNorth, BehindNorthEast,
00888                         BehindWest,        Behind,      BehindEast,
00889                         BehindSouthWest,   BehindSouth, BehindSouthEast,*/ 
00890                         Error, Error, Error, Error, Error, Error, Error, Error, Error},    
00891                     //33 - AtRearRightBorder
00892                     {   InFrontNorthWest, InFrontNorth, /*InFrontNorthEast,*/
00893                         InFrontWest,      InFront,      /*InFrontEast,*/
00894                         InFrontSouthWest, InFrontSouth, /*InFrontSouthEast,*/
00895       
00896                         NorthWest, North, /*NorthEast,*/
00897                         West,             /*East,*/
00898                         SouthWest, South, /*SouthEast,*/
00899 
00900                         /*BehindNorthWest, BehindNorth, BehindNorthEast,
00901                         BehindWest,        Behind,      BehindEast,
00902                         BehindSouthWest,   BehindSouth, BehindSouthEast,*/ 
00903                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00904                         Error, Error, Error, Error, Error, Error},    
00905                     //34 - AtRearLeftBorder
00906                     {   /*InFrontNorthWest,*/ InFrontNorth, InFrontNorthEast,
00907                         /*InFrontWest,*/      InFront,      InFrontEast,
00908                         /*InFrontSouthWest,*/ InFrontSouth, InFrontSouthEast,
00909       
00910                         /*NorthWest,*/ North, NorthEast,
00911                         /*West,*/             East,
00912                         /*SouthWest,*/ South, SouthEast, 
00913 
00914                         /*BehindNorthWest, BehindNorth,   BehindNorthEast,
00915                         BehindWest,        Behind,        BehindEast,
00916                         BehindSouthWest,   BehindSouth,   BehindSouthEast,*/ 
00917                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00918                         Error, Error, Error, Error, Error, Error},        
00919                     //35 - Nothin'
00920                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00921                         Error, Error, Error, Error, Error, Error, Error, Error, 
00922                         Error, Error, Error, Error, Error, Error, Error, Error, Error},
00923                     //36 - AtTopRearBorder
00924                     {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
00925                         InFrontWest,        InFront,        InFrontEast,
00926                         InFrontSouthWest,   InFrontSouth,   InFrontSouthEast,
00927       
00928                         /*NorthWest,    North, NorthEast,*/
00929                         West,                  East,
00930                         SouthWest,      South, SouthEast, 
00931 
00932                         /*BehindNorthWest, BehindNorth,   BehindNorthEast,
00933                         BehindWest,        Behind,        BehindEast,
00934                         BehindSouthWest,   BehindSouth,   BehindSouthEast,*/ 
00935                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00936                         Error, Error, Error, Error, Error, Error},            
00937                     //37 - AtTopRightRearBorder    
00938                     {   /*InFrontNorthWest, InFrontNorth,   InFrontNorthEast,*/
00939                         InFrontWest,        InFront,        /*InFrontEast,*/
00940                         InFrontSouthWest,   InFrontSouth,   /*InFrontSouthEast,*/
00941       
00942                         /*NorthWest, North, NorthEast,*/
00943                         West,               /*East,*/
00944                         SouthWest,   South, /*SouthEast,*/ 
00945 
00946                         /*BehindNorthWest,  BehindNorth, BehindNorthEast,
00947                         BehindWest,         Behind,      BehindEast,
00948                         BehindSouthWest,    BehindSouth, BehindSouthEast,*/ 
00949                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00950                         Error, Error, Error, Error, Error, Error,
00951                         Error, Error, Error, Error},    
00952                     //38 - AtTopLeftRearBorder
00953                     {   /*InFrontNorthWest,     InFrontNorth,    InFrontNorthEast,*/
00954                         /*InFrontWest,*/        InFront,         InFrontEast,
00955                         /*InFrontSouthWest,*/   InFrontSouth,   InFrontSouthEast,
00956       
00957                         /*NorthWest,    North,  NorthEast,*/
00958                         /*West,*/               East,
00959                         /*SouthWest,*/  South,  SouthEast, 
00960 
00961                         /*BehindNorthWest,  BehindNorth,    BehindNorthEast,
00962                         BehindWest,         Behind,         BehindEast,
00963                         BehindSouthWest,    BehindSouth,    BehindSouthEast,*/ 
00964                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00965                         Error, Error, Error, Error, Error, Error,
00966                         Error, Error, Error, Error},    
00967                     //39 - Nothin'
00968                     {   Error, Error, Error, Error, Error, Error, Error, Error, Error,
00969                         Error, Error, Error, Error, Error, Error, Error, Error, 
00970                         Error, Error, Error, Error, Error, Error, Error, Error, Error},
00971                     //40 - AtBottomRearBorder
00972                     {   InFrontNorthWest,   InFrontNorth,   InFrontNorthEast,
00973                         InFrontWest,        InFront,        InFrontEast,
00974                         /*InFrontSouthWest, InFrontSouth,   InFrontSouthEast,*/
00975       
00976                         NorthWest,      North, NorthEast,
00977                         West,                  East,
00978                         /*SouthWest,    South, SouthEast,*/ 
00979 
00980                         /*BehindNorthWest,  BehindNorth, BehindNorthEast,
00981                         BehindWest,         Behind,      BehindEast,
00982                         BehindSouthWest,    BehindSouth, BehindSouthEast,*/ 
00983                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00984                         Error, Error, Error, Error, Error, Error},    
00985                     //41 - AtBottomRightRearBorder
00986                     {   InFrontNorthWest,   InFrontNorth, /*InFrontNorthEast,*/
00987                         InFrontWest,        InFront,      /*InFrontEast,*/
00988                         /*InFrontSouthWest, InFrontSouth, InFrontSouthEast,*/
00989       
00990                         NorthWest,   North, /*NorthEast,*/
00991                         West,               /*East,*/
00992                         /*SouthWest, South, SouthEast,*/ 
00993 
00994                         /*BehindNorthWest, BehindNorth, BehindNorthEast,
00995                         BehindWest,        Behind,      BehindEast,
00996                         BehindSouthWest,   BehindSouth, BehindSouthEast,*/ 
00997                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
00998                         Error, Error, Error, Error, Error, Error,
00999                         Error, Error, Error, Error},    
01000                     //42 - AtBottomLeftRearBorder
01001                     {   /*InFrontNorthWest,*/   InFrontNorth,   InFrontNorthEast,
01002                         /*InFrontWest,*/        InFront,        InFrontEast,
01003                         /*InFrontSouthWest,     InFrontSouth,   InFrontSouthEast,*/
01004       
01005                         /*NorthWest,*/  North,  NorthEast,
01006                         /*West,*/               East,
01007                         /*SouthWest,    South,  SouthEast,*/ 
01008 
01009                         /*BehindNorthWest,  BehindNorth, BehindNorthEast,
01010                         BehindWest,         Behind,      BehindEast,
01011                         BehindSouthWest,    BehindSouth, BehindSouthEast,*/ 
01012                         Error, Error, Error, Error, Error, Error, Error, Error, Error,
01013                         Error, Error, Error, Error, Error, Error,
01014                         Error, Error, Error, Error}    
01015                };
01016         return c[b][index];
01017     }
01018         
01019     /** The valid direction three codes in anti causal direction (means: look back in scanline
01020         direction)when the center is at the volume border.
01021             Should be used with isAtVolumeBorderCausal to determine the Directions, as this
01022             avoids using of the nonesense border ids (e.g. 0,1,8,9...) of this table.
01023         \a index must be in the range <tt>0...nearBorderDirectionCount(b)-1</tt>.
01024      */
01025     static Direction nearBorderDirectionsCausal(AtVolumeBorder b, int index)
01026     {
01027         static Direction c[43][13] = {
01028             //0 - NotAtBorder -----> should never be used
01029                                 { InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
01030                                   InFrontWest,      InFront,         InFrontEast,
01031                                   InFrontSouthWest, InFrontSouth,    InFrontSouthEast,
01032                   
01033                                   NorthWest,        North,           NorthEast,
01034                                   West},                    
01035             //1 - AtRightBorder -----> should never be used
01036                                 { InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
01037                                   InFrontWest,      InFront,         InFrontEast,
01038                                   InFrontSouthWest, InFrontSouth,    InFrontSouthEast,
01039                   
01040                                   NorthWest,        North,           NorthEast,
01041                                   West},    
01042             //2 - AtLeftBorder
01043                                 { /*InFrontNorthWest,*/ InFrontNorth,InFrontNorthEast,
01044                                   /*InFrontWest,*/  InFront,         InFrontEast,
01045                                   /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
01046                   
01047                                   /*NorthWest,*/    North,           NorthEast,
01048                                   /*West*/
01049                                   Error, Error, Error, Error, Error},    
01050             //3 - Nothin'
01051                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01052             //4 - AtTopBorder
01053                                 { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,*/
01054                                   InFrontWest,       InFront,        InFrontEast,
01055                                   InFrontSouthWest,  InFrontSouth,   InFrontSouthEast,
01056                   
01057                                   /*NorthWest,       North,          NorthEast,*/
01058                                   West,
01059                                   Error, Error, Error, Error, Error, Error},    
01060             //5 - AtTopRightBorder
01061                                 { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,*/
01062                                   InFrontWest,       InFront,        /*InFrontEast,*/
01063                                   InFrontSouthWest,  InFrontSouth,   /*InFrontSouthEast,*/
01064                   
01065                                   /*NorthWest, North, NorthEast,*/
01066                                   West,
01067                                   Error, Error, Error, Error, Error, Error, Error, Error},    
01068             //6 - AtTopLeftBorder
01069                                 { /*InFrontNorthWest,InFrontNorth,    InFrontNorthEast,*/
01070                                   /*InFrontWest,*/   InFront,         InFrontEast,
01071                                   /*InFrontSouthWest,*/InFrontSouth,  InFrontSouthEast,
01072                   
01073                                   /*NorthWest,       North,           NorthEast,*/
01074                                   /*West,*/
01075                                   Error, Error, Error, Error, Error, Error, Error, Error, Error},
01076             //7 - Nothin'
01077                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01078             //8 - AtBottomBorder -----> should never be used
01079                                 { InFrontNorthWest,  InFrontNorth,    InFrontNorthEast,
01080                                   InFrontWest,       InFront,         InFrontEast,
01081                                   InFrontSouthWest,  InFrontSouth,    InFrontSouthEast,
01082                   
01083                                   NorthWest,         North,           NorthEast,
01084                                   West},    
01085             //9 - AtBottomRightBorder -----> should never be used
01086                                 { InFrontNorthWest, InFrontNorth,    InFrontNorthEast,
01087                                   InFrontWest,      InFront,         InFrontEast,
01088                                   InFrontSouthWest, InFrontSouth,    InFrontSouthEast,
01089                   
01090                                   NorthWest,        North,           NorthEast,
01091                                   West},    
01092             //10 - AtBottomLeftBorder
01093                                 { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
01094                                   /*InFrontWest,*/  InFront,         InFrontEast,
01095                                   /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
01096                   
01097                                   /*NorthWest,*/    North,           NorthEast,
01098                                   /*West*/
01099                                   Error, Error, Error, Error, Error},    
01100             //11 - Nothin'
01101                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01102             //12 - Nothin'
01103                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01104             //13 - Nothin'
01105                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01106             //14 - Nothin'
01107                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01108             //15 - Nothin'
01109                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01110             //16 - AtFrontBorder
01111                                 { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
01112                                   InFrontWest,      InFront,         InFrontEast,
01113                                   InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
01114                   
01115                                   NorthWest,        North,           NorthEast,
01116                                   West,
01117                                   Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01118             //17 - AtFrontRightBorder
01119                                 { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
01120                                   InFrontWest,      InFront,         InFrontEast,
01121                                   InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
01122                   
01123                                   NorthWest,        North,           /*NorthEast,*/
01124                                   West,
01125                                   Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01126             //18 - AtFrontLeftBorder
01127                                 { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
01128                                   InFrontWest,      InFront,         InFrontEast,
01129                                   InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
01130                   
01131                                   /*NorthWest,*/    North,           NorthEast,
01132                                   /*West,*/
01133                                   Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01134             //19 - Nothin'
01135                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01136             //20 - AtTopFrontBorder
01137                                 { /*InFrontNorthWest,InFrontNorth,   InFrontNorthEast,
01138                                   InFrontWest,      InFront,         InFrontEast,
01139                                   InFrontSouthWest, InFrontSouth,    InFrontSouthEast,*/
01140                   
01141                                   /*NorthWest, North, NorthEast,*/
01142                                   West,
01143                                   Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01144             //21 - AtTopRightFrontBorder
01145                                 { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
01146                                   InFrontWest,        InFront,       InFrontEast,
01147                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
01148                   
01149                                   /*NorthWest,        North,         NorthEast,*/
01150                                   West,
01151                                   Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01152             //22 - AtTopLeftFrontBorder
01153                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01154             //23 - Nothin
01155                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01156             //24 - AtBottomFrontBorder
01157                                 { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
01158                                   InFrontWest,        InFront,       InFrontEast,
01159                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
01160                   
01161                                   NorthWest,          North,         NorthEast,
01162                                   West,
01163                                   Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01164             //25 - AtBottomRightFrontBorder
01165                                 { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
01166                                   InFrontWest,        InFront,       InFrontEast,
01167                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
01168                   
01169                                   NorthWest,          North,         /*NorthEast,*/
01170                                   West,
01171                                   Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01172             //26 - AtBottomLeftFrontBorder
01173                                 { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,
01174                                   InFrontWest,        InFront,       InFrontEast,
01175                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,*/
01176                   
01177                                   /*NorthWest,*/      North,         NorthEast,
01178                                   West,
01179                                   Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01180             //27 - Nothin
01181                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01182             //28 - Nothin
01183                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01184             //29 - Nothin
01185                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01186             //30 - Nothin
01187                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01188             //31 - Nothin
01189                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01190             //32 - AtRearBorder -----> should never be used
01191                                 { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
01192                                   InFrontWest,        InFront,       InFrontEast,
01193                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
01194                   
01195                                   NorthWest,          North,         NorthEast,
01196                                   West},    
01197             //33 - AtRearRightBorder -----> should never be used
01198                                 { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
01199                                   InFrontWest,        InFront,       InFrontEast,
01200                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
01201                   
01202                                   NorthWest,          North,         NorthEast,
01203                                   West},    
01204             //34 - AtRearLeftBorder
01205                                 { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
01206                                   /*InFrontWest,*/    InFront,       InFrontEast,
01207                                   /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
01208                   
01209                                   /*NorthWest,*/      North,         NorthEast,
01210                                   /*West*/
01211                                   Error, Error, Error, Error, Error},    
01212             //35 - Nothin
01213                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01214             //36 - AtTopRearBorder    
01215                                 { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
01216                                   InFrontWest,        InFront,       InFrontEast,
01217                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
01218                   
01219                                   /*NorthWest,        North,         NorthEast,*/
01220                                   West,
01221                                   Error, Error, Error, Error, Error, Error},    
01222             //37 - AtTopRightRearBorder        
01223                                 { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
01224                                   InFrontWest,        InFront,       /*InFrontEast,*/
01225                                   InFrontSouthWest,   InFrontSouth,  /*InFrontSouthEast,*/
01226                   
01227                                   /*NorthWest,        North,         NorthEast,*/
01228                                   West,
01229                                   Error, Error, Error, Error, Error, Error, Error, Error},
01230             //38 - AtTopLeftRearBorder    
01231                                 { /*InFrontNorthWest, InFrontNorth,  InFrontNorthEast,*/
01232                                   /*InFrontWest,*/    InFront,       InFrontEast,
01233                                   /*InFrontSouthWest,*/InFrontSouth, InFrontSouthEast,
01234                   
01235                                   /*NorthWest, North, NorthEast,*/
01236                                   /*West,*/
01237                                   Error, Error, Error, Error, Error, Error, Error, Error, Error},
01238             //39 - Nothin
01239                                 { Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error, Error},    
01240             //40 - AtBottomRearBorder -----> should never be used
01241                                 { InFrontNorthWest,   InFrontNorth,  InFrontNorthEast,
01242                                   InFrontWest,        InFront,       InFrontEast,
01243                                   InFrontSouthWest,   InFrontSouth,  InFrontSouthEast,
01244                   
01245                                   NorthWest,          North,         NorthEast,
01246                                   West},    
01247             //41 - AtBottomRightRearBorder -----> should never be used
01248                                 { InFrontNorthWest,  InFrontNorth,   InFrontNorthEast,
01249                                   InFrontWest,       InFront,        InFrontEast,
01250                                   InFrontSouthWest,  InFrontSouth,   InFrontSouthEast,
01251                   
01252                                   NorthWest,         North,          NorthEast,
01253                                   West},    
01254             //42 - AtBottomLeftRearBorder
01255                                 { /*InFrontNorthWest,*/InFrontNorth, InFrontNorthEast,
01256                                   /*InFrontWest,*/   InFront,        InFrontEast,
01257                                   /*InFrontSouthWest,InFrontSouth,   InFrontSouthEast,*/
01258                   
01259                                   /*NorthWest,*/     North,          NorthEast,
01260                                   /*West*/
01261                                   Error, Error, Error, Error, Error, Error, Error}    
01262         };
01263         return c[b][index];
01264     }
01265     
01266     /** transform direction code into corresponding Diff3D offset.
01267         (note: there is no bounds checking on the code you pass.)
01268     */
01269     static Diff3D const & diff(Direction code)
01270     {
01271         static Diff3D d[] = {   Diff3D( -1, -1, -1),  //InFrontNorthWest
01272                                 Diff3D(  0, -1, -1),  //InFrontNorth
01273                                 Diff3D(  1, -1, -1),  //InFrontNorthEast
01274                                 Diff3D( -1,  0, -1),  //InFrontWest
01275                                 Diff3D(  0,  0, -1),  //InFront
01276                                 Diff3D(  1,  0, -1),  //InFrontEast
01277                                 Diff3D( -1,  1, -1),  //InFrontSouthWest
01278                                 Diff3D(  0,  1, -1),  //InFrontSouth
01279                                 Diff3D(  1,  1, -1),  //InFrontSouthEast
01280 
01281                                 Diff3D( -1, -1,  0),  //NorthWest
01282                                 Diff3D(  0, -1,  0),  //North
01283                                 Diff3D(  1, -1,  0),  //NorthEast
01284                                 Diff3D( -1,  0,  0),  //West
01285                                 Diff3D(  1,  0,  0),  //East
01286                                 Diff3D( -1,  1,  0),  //SouthWest
01287                                 Diff3D(  0,  1,  0),  //South
01288                                 Diff3D(  1,  1,  0),  //SouthEast
01289 
01290                                 Diff3D( -1, -1,  1),  //BehindNorthWest
01291                                 Diff3D(  0, -1,  1),  //BehindNorth
01292                                 Diff3D(  1, -1,  1),  //BehindNorthEast
01293                                 Diff3D( -1,  0,  1),  //BehindWest
01294                                 Diff3D(  0,  0,  1),  //Behind
01295                                 Diff3D(  1,  0,  1),  //BehindEast
01296                                 Diff3D( -1,  1,  1),  //BehindSouthWest
01297                                 Diff3D(  0,  1,  1),  //BehindSouth
01298                                 Diff3D(  1,  1,  1),  //BehindSouthEast
01299                             };
01300         return d[code];
01301     }
01302 
01303     /** Equivalent to <tt>diff(static_cast<Direction>(code))</tt>.
01304         (note: there is no bounds checking on the code you pass.)
01305     */
01306     static Diff3D const & diff(int code) { return diff(static_cast<Direction>(code)); }
01307 
01308     /**  Equivalent to <tt>diff(code)[dim]</tt> */
01309     static int diff(Direction code, int dim) { return diff(code)[dim]; }
01310    
01311     /** Get the relative offset from one neighbor to the other.
01312     For example, <tt>relativeDiff(East, West) == multi_differencetype(-2,0,0)</tt>.
01313     (note: there is no bounds checking on the code you pass.)
01314     */
01315     static Diff3D const relativeDiff(Direction fromCode, Direction toCode)
01316     {
01317         //Uncomment the following lines may cause the program to crash because of insufficient
01318         //static allocatable memory on the stack
01319         /*
01320             static Diff3D d[][] = {
01321                 //   InFront-NW    ---     InFront-N   ---     InFront-NE  ---    Infront-W    ---     InFront     ---   InFront-E     ---   InFront-SW    ---      InFront-S  ---   InFront-SE    ---    NorthWest   ---       North      ---    NorthEast    ---      West      ---       East       ---    SouthWest    ---    South        ---     SouthEast  ---     Behind-NW    ---     Behind-N    ---      Behind-NE  ---     Behind-W    ---      Behind     ---    Behind-E     ---    Behind-SW    ---      Behind-S   ---    Behind-SE  
01322                 {    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2, 2,  0),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 2,  1,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D( 2,  2,  1),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D( 2,  0,  2),    Diff3D( 0,  1,  2),    Diff3D( 1,  1,  2), Diff3D( 2,  1,  2),    Diff3D( 0,  2,  2),    Diff3D( 1,  2,  2),    Diff3D( 2,  2,  2)    },    //InFront-NW  
01323                 {    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1, 2,  0),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 1,  1,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D(-1,  1,  2),    Diff3D( 0,  1,  2), Diff3D( 1,  1,  2),    Diff3D(-1,  2,  2),    Diff3D( 0,  2,  2),    Diff3D( 1,  2,  2)    },    //InFront-N  
01324                 {    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0, 2,  0),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D( 0,  1,  1),    Diff3D(-2,  2,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D(-2,  0,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D(-2,  1,  2),    Diff3D(-1,  1,  2), Diff3D( 0,  1,  2),    Diff3D(-2,  2,  2),    Diff3D(-1,  2,  2),    Diff3D( 0,  2,  2)    },    //InFront-NE
01325                 {    Diff3D(0,  -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2, 1,  0),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D( 2,  1,  1),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2),    Diff3D( 2, -1,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2), Diff3D( 2,  0,  2),    Diff3D( 0,  1,  2),    Diff3D( 1,  1,  2),    Diff3D( 2,  1,  2)    },    //Infront-W
01326                 {    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1, 1,  0),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2), Diff3D( 1,  0,  2),    Diff3D(-1,  1,  2),    Diff3D( 0,  1,  2),    Diff3D( 1,  1,  2)    },    //InFront
01327                 {    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0, 1,  0),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1),    Diff3D(-2, -1,  2),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2),    Diff3D(-2,  0,  2),    Diff3D(-1,  0,  2), Diff3D( 0,  0,  2),    Diff3D(-2,  1,  2),    Diff3D(-1,  1,  2),    Diff3D( 0,  1,  2)    },    //InFront-E
01328                 {    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2, 0,  0),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D( 2, -2,  1),    Diff3D( 0, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0, -2,  2),    Diff3D( 1, -2,  2),    Diff3D( 2, -2,  2),    Diff3D( 0, -1,  2),    Diff3D( 1, -1,  2), Diff3D( 2, -1,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2),    Diff3D( 2,  0,  2)    },    //InFront-SW
01329                 {    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1, 0,  0),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D(-1, -1,  1),    Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1, -2,  2),    Diff3D( 0, -2,  2),    Diff3D( 1, -2,  2),    Diff3D(-1, -1,  2),    Diff3D( 0, -1,  2), Diff3D( 1, -1,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2),    Diff3D( 1,  0,  2)    },    //InFront-S 
01330                 {    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0, 0,  0),    Diff3D(-2, -2,  1),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D(-2, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2, -2,  2),    Diff3D(-1, -2,  2),    Diff3D( 0, -2,  2),    Diff3D(-2, -1,  2),    Diff3D(-1, -1,  2), Diff3D( 0, -1,  2),    Diff3D(-2,  0,  2),    Diff3D(-1,  0,  2),    Diff3D( 0,  0,  2)    },    //InFront-SE
01331                 {    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D( 2, 2, -1),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2,  2,  0),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1), Diff3D( 2,  1,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1),    Diff3D( 2,  2,  1)    },    //NorthWest
01332                 {    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D( 1, 2, -1),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1), Diff3D( 1,  1,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1),    Diff3D( 1,  2,  1)    },    //North
01333                 {    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2,  2, -1),    Diff3D(-1,  2, -1),    Diff3D( 0, 2, -1),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D(-1,  1,  1), Diff3D( 0,  1,  1),    Diff3D(-2,  2,  1),    Diff3D(-1,  2,  1),    Diff3D( 0,  2,  1)    },    //NortEast
01334                 {    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2, 1, -1),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1),    Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1), Diff3D( 2,  0,  1),    Diff3D( 0,  1,  1),    Diff3D( 1,  1,  1),    Diff3D( 2,  1,  1)    },    //West
01335                 {    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0, 1, -1),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1), Diff3D( 0,  0,  1),    Diff3D(-2,  1,  1),    Diff3D(-1,  1,  1),    Diff3D( 0,  1,  1)    },    //East
01336                 {    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D( 2, -2, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2, 0, -1),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D( 2, -2,  1),    Diff3D( 0, -1,  1),    Diff3D( 1, -1,  1), Diff3D( 2, -1,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1),    Diff3D( 2,  0,  1)    },    //SouthWest
01337                 {    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1, 0, -1),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D( 1, -2,  1),    Diff3D(-1, -1,  1),    Diff3D( 0, -1,  1), Diff3D( 1, -1,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1),    Diff3D( 1,  0,  1)    },    //South
01338                 {    Diff3D(-2, -2, -1),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0, 0, -1),    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2, -2,  1),    Diff3D(-1, -2,  1),    Diff3D( 0, -2,  1),    Diff3D(-2, -1,  1),    Diff3D(-1, -1,  1), Diff3D( 0, -1,  1),    Diff3D(-2,  0,  1),    Diff3D(-1,  0,  1),    Diff3D( 0,  0,  1)    },    //SouthEast
01339                 {    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2,  0, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D( 2,  1, -2),    Diff3D( 0,  2, -2),    Diff3D( 1,  2, -2),    Diff3D( 2, 2, -2),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D( 2,  2, -1),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0),    Diff3D( 2,  2,  0)    },    //Behind-NW
01340                 {    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D(-1,  2, -2),    Diff3D( 0,  2, -2),    Diff3D( 1, 2, -2),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D( 1,  2, -1),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0),    Diff3D( 1,  2,  0)    },    //Behind-N
01341                 {    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D(-2,  1, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D(-2,  2, -2),    Diff3D(-1,  2, -2),    Diff3D( 0, 2, -2),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2,  2, -1),    Diff3D(-1,  2, -1),    Diff3D( 0,  2, -1),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D(-2,  2,  0),    Diff3D(-1,  2,  0),    Diff3D( 0,  2,  0)    },    //Behind-NE
01342                 {    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D( 2, -1, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2,  0, -2),    Diff3D( 0,  1, -2),    Diff3D( 1,  1, -2),    Diff3D( 2, 1, -2),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D( 2,  1, -1),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0), Diff3D( 2,  0,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0),    Diff3D( 2,  1,  0)    },    //Behind-W
01343                 {    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D(-1,  1, -2),    Diff3D( 0,  1, -2),    Diff3D( 1, 1, -2),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D( 1,  1, -1),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0), Diff3D( 1,  0,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0),    Diff3D( 1,  1,  0)    },    //Behind
01344                 {    Diff3D(-2, -1, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D(-2,  1, -2),    Diff3D(-1,  1, -2),    Diff3D( 0, 1, -2),    Diff3D(-2, -1, -1),    Diff3D(-1, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2,  1, -1),    Diff3D(-1,  1, -1),    Diff3D( 0,  1, -1),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0), Diff3D( 0,  0,  0),    Diff3D(-2,  1,  0),    Diff3D(-1,  1,  0),    Diff3D( 0,  1,  0)    },    //Behind-E
01345                 {    Diff3D( 0, -2, -2),    Diff3D( 1, -2, -2),    Diff3D( 2, -2, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D( 2, -1, -2),    Diff3D( 0,  0, -2),    Diff3D( 1,  0, -2),    Diff3D( 2, 0, -2),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D( 2, -2, -1),    Diff3D( 0, -1, -1),    Diff3D( 2, -1, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D( 2,  0, -1),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D( 2, -2,  0),    Diff3D( 0, -1,  0),    Diff3D( 1, -1,  0), Diff3D( 2, -1,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0),    Diff3D( 2,  0,  0)    },    //Behind-SW
01346                 {    Diff3D(-1, -2, -2),    Diff3D( 0, -2, -2),    Diff3D( 1, -2, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D( 1, -1, -2),    Diff3D(-1,  0, -2),    Diff3D( 0,  0, -2),    Diff3D( 1, 0, -2),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D( 1, -2, -1),    Diff3D(-1, -1, -1),    Diff3D( 1, -1, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D( 1,  0, -1),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D( 1, -2,  0),    Diff3D(-1, -1,  0),    Diff3D( 0, -1,  0), Diff3D( 1, -1,  0),    Diff3D(-1,  0,  0),    Diff3D( 0,  0,  0),    Diff3D( 1,  0,  0)    },    //Behind-S
01347                 {    Diff3D(-2, -2, -2),    Diff3D(-1, -2, -2),    Diff3D( 0, -2, -2),    Diff3D(-2, -1, -2),    Diff3D(-1, -1, -2),    Diff3D( 0, -1, -2),    Diff3D(-2,  0, -2),    Diff3D(-1,  0, -2),    Diff3D( 0, 0, -2),    Diff3D(-2, -2, -1),    Diff3D(-1, -2, -1),    Diff3D( 0, -2, -1),    Diff3D(-2, -1, -1),    Diff3D( 0, -1, -1),    Diff3D(-2,  0, -1),    Diff3D(-1,  0, -1),    Diff3D( 0,  0, -1),    Diff3D(-2, -2,  0),    Diff3D(-1, -2,  0),    Diff3D( 0, -2,  0),    Diff3D(-2, -1,  0),    Diff3D(-1, -1,  0), Diff3D( 0, -1,  0),    Diff3D(-2,  0,  0),    Diff3D(-1,  0,  0), Diff3D( 0,  0,  0)    }        //Behind-SE
01348             };
01349             return d[fromCode][toCode];
01350         */
01351         return diff(toCode)-diff(fromCode);
01352     }
01353 
01354    /** Equivalent to relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode)).
01355        (note: there is no bounds checking on the code you pass.)
01356    */
01357     static Diff3D const relativeDiff(int fromCode, int toCode)
01358     {
01359         return relativeDiff(static_cast<Direction>(fromCode), static_cast<Direction>(toCode));
01360     }
01361     
01362     /**  X-component of diff() */
01363     static int dX(Direction code) { return diff(code)[0]; }
01364     /**  Y-component of diff() */
01365     static int dY(Direction code) { return diff(code)[1]; }
01366     /**  Z-component of diff() */
01367     static int dZ(Direction code) { return diff(code)[2]; }
01368     
01369     /**  X-component of diff() */
01370     static int dX(int code) { return diff(code)[0]; }
01371     /**  Y-component of diff() */
01372     static int dY(int code) { return diff(code)[1]; }
01373     /**  Z-component of diff() */
01374     static int dZ(int code) { return diff(code)[2]; }
01375     
01376     /** transform 6-neighborhood code into 26-neighborhood code.
01377      */
01378     static Direction code(Neighborhood3DSix::Direction d)
01379     {
01380         switch (d){
01381             case Neighborhood3DSix::InFront :
01382                     return InFront;
01383             case Neighborhood3DSix::North :
01384                     return North;
01385             case Neighborhood3DSix::West :
01386                     return West;
01387             case Neighborhood3DSix::East :
01388                     return East;
01389             case Neighborhood3DSix::South :
01390                     return South;
01391             case Neighborhood3DSix::Behind :
01392                     return Behind;
01393         }
01394         return Error;
01395     }
01396 
01397     /** transform Diff3D offset into corresponding direction code.
01398        The code <tt>Direction::Error</tt> will be returned if <tt>diff</tt>
01399        is not in the 3DTwentySix-Neighborhood.
01400     */
01401     static Direction code(Diff3D const & diff)
01402     {
01403         switch(diff[0]){
01404             case -1:
01405                 switch(diff[1]){
01406                     case -1:
01407                         switch(diff[2]){
01408                             case -1: return InFrontNorthWest; // ( -1, -1, -1)
01409                             case  0: return NorthWest;        // ( -1, -1,  0)
01410                             case  1: return BehindNorthWest;  // ( -1, -1,  1)
01411                         }
01412                     case  0:
01413                         switch(diff[2]){
01414                             case -1: return InFrontWest;      // ( -1,  0, -1)
01415                             case  0: return West;             // ( -1,  0,  0)
01416                             case  1: return BehindWest;       // ( -1,  0,  1)
01417                         }
01418                     case  1:
01419                         switch(diff[2]){
01420                             case -1: return InFrontSouthWest; // ( -1,  1, -1)
01421                             case  0: return SouthWest;        // ( -1,  1,  0)
01422                             case  1: return BehindSouthWest;  // ( -1,  1,  1)
01423                         }
01424                 }
01425             case  0:
01426                 switch(diff[1]){
01427                     case -1:
01428                         switch(diff[2]){
01429                             case -1: return InFrontNorth;     // (  0,  0, -1)
01430                             case  0: return North;            // (  0, -1,  0)
01431                             case  1: return BehindNorth;      // (  0, -1,  1)
01432                         }
01433                     case  0:
01434                         switch(diff[2]){
01435                             case -1: return InFront;          // (  0,  0, -1)
01436                             case  1: return Behind;           // (  0,  0,  1)
01437                         }
01438                     case  1: 
01439                         switch(diff[2]){
01440                             case -1: return InFrontSouth;     // (  0,  1, -1)
01441                             case  0: return South;            // (  0,  1,  0)
01442                             case  1: return BehindSouth;      // (  0,  1,  1)
01443                         }
01444                 }                    
01445             case  1:
01446                 switch(diff[1]){
01447                     case -1:
01448                         switch(diff[2]){
01449                             case -1: return InFrontNorthEast;  // (  1, -1, -1)
01450                             case  0: return NorthEast;         // (  1, -1,  0)
01451                             case  1: return BehindNorthEast;   // (  1, -1,  1)
01452                         }
01453                     case  0:
01454                         switch(diff[2]){
01455                             case -1: return InFrontEast;       // (  1,  0, -1)
01456                             case  0: return East;              // (  1,  0,  0)
01457                             case  1: return BehindEast;        // (  1,  0,  1)
01458                         }
01459                     case  1:
01460                         switch(diff[2]){
01461                             case -1: return InFrontSouthEast;  // (  1,  1, -1)
01462                             case  0: return SouthEast;         // (  1,  1,  0)
01463                             case  1: return BehindSouthEast;   // (  1,  1,  1)
01464                         }
01465                 }
01466         }
01467         return Error; // better safe than sorry
01468     }
01469   
01470     /** Check whether a code refers to a diagonal direction.
01471         Useful if you want to abstract the differences between 6- and 26-neighborhood.
01472         Always <tt>false</tt> for 6-neighborhood.
01473     */
01474     static bool isDiagonal(Direction dir) {
01475         Diff3D d = diff(dir);
01476         if (abs(d[0])+abs(d[1])+abs(d[2])==1)
01477             return false;
01478         else
01479             return true;
01480     }
01481 
01482     static Diff3D const & frontTopLeft()        { return diff(InFrontNorthWest); }    /**<  Offset to the front-top-left neighbor */
01483     static Diff3D const & frontTop()            { return diff(InFrontNorth); }        /**<  Offset to the front-top neighbor */
01484     static Diff3D const & frontTopRight()       { return diff(InFrontNorthEast); }    /**<  Offset to the front-top-right neighbor */
01485     static Diff3D const & frontLeft()           { return diff(InFrontWest); }         /**<  Offset to the front-left neighbor */
01486     static Diff3D const & front()               { return diff(InFront); }             /**<  Offset to the front neighbor */
01487     static Diff3D const & frontRight()          { return diff(InFrontEast); }         /**<  Offset to the front-right neighbor */
01488     static Diff3D const & frontBottomLeft()     { return diff(InFrontSouthWest); }    /**<  Offset to the front-bottom-left neighbor */
01489     static Diff3D const & frontBottom()         { return diff(InFrontSouth); }        /**<  Offset to the front-bottom neighbor */
01490     static Diff3D const & frontBottomRight()    { return diff(InFrontSouthEast); }    /**<  Offset to the front-bottom-right neighbor */
01491     
01492     static Diff3D const & topLeft()             { return diff(NorthWest); }           /**<  Offset to the top-left neighbor */
01493     static Diff3D const & top()                 { return diff(North); }               /**<  Offset to the top neighbor */
01494     static Diff3D const & topRight()            { return diff(NorthEast); }           /**<  Offset to the top-right neighbor */
01495     static Diff3D const & left()                { return diff(West); }                /**<  Offset to the left neighbor */
01496     static Diff3D const & right()               { return diff(East); }                /**<  Offset to the right neighbor */
01497     static Diff3D const & bottomLeft()          { return diff(SouthWest); }           /**<  Offset to the bottom-left neighbor */
01498     static Diff3D const & bottom()              { return diff(South); }               /**<  Offset to the bottom neighbor */
01499     static Diff3D const & bottomRight()         { return diff(SouthEast); }           /**<  Offset to the bottom-right neighbor */
01500 
01501     static Diff3D const & rearTopLeft()         { return diff(BehindNorthWest); }     /**<  Offset to the rear-top-left neighbor */
01502     static Diff3D const & rearTop()             { return diff(BehindNorth); }         /**<  Offset to the rear-top neighbor */
01503     static Diff3D const & rearTopRight()        { return diff(BehindNorthEast); }     /**<  Offset to the rear-top-right neighbor */
01504     static Diff3D const & rearLeft()            { return diff(BehindWest); }          /**<  Offset to the rear-left neighbor */
01505     static Diff3D const & rear()                { return diff(Behind); }              /**<  Offset to the rear neighbor */
01506     static Diff3D const & rearRight()           { return diff(BehindEast); }          /**<  Offset to the rear-right neighbor */
01507     static Diff3D const & rearBottomLeft()      { return diff(BehindSouthWest); }     /**<  Offset to the rear-bottom-left neighbor */
01508     static Diff3D const & rearBottom()          { return diff(BehindSouth); }         /**<  Offset to the rear-bottom neighbor */
01509     static Diff3D const & rearBottomRight()     { return diff(BehindSouthEast); }     /**<  Offset to the rear-bottom-right neighbor */
01510 
01511     //----- other namings
01512 
01513     static Diff3D const & infrontNorthWest()    { return diff(InFrontNorthWest); }    /**<  Offset to the infront-north-west neighbor */
01514     static Diff3D const & infrontNorth()        { return diff(InFrontNorth); }        /**<  Offset to the infront-north neighbor */
01515     static Diff3D const & infrontNorthEast()    { return diff(InFrontNorthEast); }    /**<  Offset to the infront-north-east neighbor */
01516     static Diff3D const & infrontWest()         { return diff(InFrontWest); }         /**<  Offset to the infront-west neighbor */
01517     static Diff3D const & infront()             { return diff(InFront); }             /**<  Offset to the infront neighbor */
01518     static Diff3D const & infrontEast()         { return diff(InFrontEast); }         /**<  Offset to the infront-east neighbor */
01519     static Diff3D const & infrontSouthWest()    { return diff(InFrontSouthWest); }    /**<  Offset to the infront-south-west neighbor */
01520     static Diff3D const & infrontSouth()        { return diff(InFrontSouth); }        /**<  Offset to the infront-south neighbor */
01521     static Diff3D const & infrontSouthEast()    { return diff(InFrontSouthEast); }    /**<  Offset to the infront-south-east neighbor */
01522     
01523     static Diff3D const & northWest()           { return diff(NorthWest); }            /**<  Offset to the north-west neighbor */
01524     static Diff3D const & north()               { return diff(North); }                /**<  Offset to the north neighbor */
01525     static Diff3D const & northEast()           { return diff(NorthEast); }            /**<  Offset to the north-east neighbor */
01526     static Diff3D const & west()                { return diff(West); }                 /**<  Offset to the west neighbor */
01527     static Diff3D const & east()                { return diff(East); }                 /**<  Offset to the right neighbor */
01528     static Diff3D const & southWest()           { return diff(SouthWest); }            /**<  Offset to the south-west neighbor */
01529     static Diff3D const & south()               { return diff(South); }                /**<  Offset to the south neighbor */
01530     static Diff3D const & southEast()           { return diff(SouthEast); }            /**<  Offset to the south-east neighbor */
01531 
01532     static Diff3D const & behindNorthWest()     { return diff(BehindNorthWest); }      /**<  Offset to the behind-north-west neighbor */
01533     static Diff3D const & behindNorth()         { return diff(BehindNorth); }          /**<  Offset to the behind-north neighbor */
01534     static Diff3D const & behindNorthEast()     { return diff(BehindNorthEast); }      /**<  Offset to the behind-north-east neighbor */
01535     static Diff3D const & behindEast()          { return diff(BehindWest); }           /**<  Offset to the behind-west neighbor */
01536     static Diff3D const & behind()              { return diff(Behind); }               /**<  Offset to the behind neighbor */
01537     static Diff3D const & behindWest()          { return diff(BehindEast); }           /**<  Offset to the behind-right neighbor */
01538     static Diff3D const & behindSouthWest()     { return diff(BehindSouthWest); }      /**<  Offset to the behind-south-west neighbor */
01539     static Diff3D const & behindSouth()         { return diff(BehindSouth); }          /**<  Offset to the behind-south neighbor */
01540     static Diff3D const & behindSouthEast()     { return diff(BehindSouthEast); }      /**<  Offset to the behind-south-east neighbor */
01541 }; // class Neighborhood3D
01542 
01543 
01544 /** Export NeighborCode3D::Direction into the scope of namespace Neighborhood3DSix.
01545  */
01546 typedef NeighborCode3D::Direction Direction;
01547 
01548 static const Direction InFrontNorthWest   = NeighborCode3D::InFrontNorthWest;     /**<  Export NeighborCode3D::InFrontNorthWest to namespace Neighborhood3DTwentySix */
01549 static const Direction InFrontNorth       = NeighborCode3D::InFrontNorth;         /**<  Export NeighborCode3D::InFrontNorth to namespace Neighborhood3DTwentySix */
01550 static const Direction InFrontNorthEast   = NeighborCode3D::InFrontNorthEast;     /**<  Export NeighborCode3D::InFrontNorthEast to namespace Neighborhood3DTwentySix */
01551 static const Direction InFrontWest        = NeighborCode3D::InFrontWest;          /**<  Export NeighborCode3D::InFrontWest to namespace Neighborhood3DTwentySix */
01552 static const Direction InFront            = NeighborCode3D::InFront;              /**<  Export NeighborCode3D::InFront to namespace Neighborhood3DTwentySix */
01553 static const Direction InFrontEast        = NeighborCode3D::InFrontEast;          /**<  Export NeighborCode3D::InFrontEast to namespace Neighborhood3DTwentySix */
01554 static const Direction InFrontSouthWest   = NeighborCode3D::InFrontSouthWest;     /**<  Export NeighborCode3D::InFrontSouthWest to namespace Neighborhood3DTwentySix */
01555 static const Direction InFrontSouth       = NeighborCode3D::InFrontSouth;         /**<  Export NeighborCode3D::InFrontSouth to namespace Neighborhood3DTwentySix */
01556 static const Direction InFrontSouthEast   = NeighborCode3D::InFrontSouthEast;     /**<  Export NeighborCode3D::InFrontSouthEast to namespace Neighborhood3DTwentySix */
01557 
01558 static const Direction NorthWest          = NeighborCode3D::NorthWest;            /**<  Export NeighborCode3D::NorthWest to namespace Neighborhood3DTwentySix */
01559 static const Direction North              = NeighborCode3D::North;                /**<  Export NeighborCode3D::North to namespace Neighborhood3DTwentySix */
01560 static const Direction NorthEast          = NeighborCode3D::NorthEast;            /**<  Export NeighborCode3D::NorthEast to namespace Neighborhood3DTwentySix */
01561 static const Direction West               = NeighborCode3D::West;                 /**<  Export NeighborCode3D::West to namespace Neighborhood3DTwentySix */
01562 static const Direction East               = NeighborCode3D::East;                 /**<  Export NeighborCode3D::East to namespace Neighborhood3DTwentySix */
01563 static const Direction SouthWest          = NeighborCode3D::SouthWest;            /**<  Export NeighborCode3D::SouthWest to namespace Neighborhood3DTwentySix */
01564 static const Direction South              = NeighborCode3D::South;                /**<  Export NeighborCode3D::South to namespace Neighborhood3DTwentySix */
01565 static const Direction SouthEast          = NeighborCode3D::SouthEast;            /**<  Export NeighborCode3D::SouthEast to namespace Neighborhood3DTwentySix */
01566 
01567 static const Direction BehindNorthWest    = NeighborCode3D::BehindNorthWest;      /**<  Export NeighborCode3D::BehindNorthWest to namespace Neighborhood3DTwentySix */
01568 static const Direction BehindNorth        = NeighborCode3D::BehindNorth;          /**<  Export NeighborCode3D::BehindNorth to namespace Neighborhood3DTwentySix */
01569 static const Direction BehindNorthEast    = NeighborCode3D::BehindNorthEast;      /**<  Export NeighborCode3D::BehindNorthEast to namespace Neighborhood3DTwentySix */
01570 static const Direction BehindWest         = NeighborCode3D::BehindWest;           /**<  Export NeighborCode3D::BehindWest to namespace Neighborhood3DTwentySix */
01571 static const Direction Behind             = NeighborCode3D::Behind;               /**<  Export NeighborCode3D::Behind to namespace Neighborhood3DTwentySix */
01572 static const Direction BehindEast         = NeighborCode3D::BehindEast;           /**<  Export NeighborCode3D::BehindEast to namespace Neighborhood3DTwentySix */
01573 static const Direction BehindSouthWest    = NeighborCode3D::BehindSouthWest;      /**<  Export NeighborCode3D::BehindSouthWest to namespace Neighborhood3DTwentySix */
01574 static const Direction BehindSouth        = NeighborCode3D::BehindSouth;          /**<  Export NeighborCode3D::BehindSouth to namespace Neighborhood3DTwentySix */
01575 static const Direction BehindSouthEast    = NeighborCode3D::BehindSouthEast;      /**<  Export NeighborCode3D::BehindSouthEast to namespace Neighborhood3DTwentySix */
01576 
01577 static const Direction DirectionCount     = NeighborCode3D::DirectionCount;       /**<  Export NeighborCode3D::DirectionCount to namespace Neighborhood3DTwentySix */
01578 
01579 }//namespace Neighborhood3DTwentySix
01580     
01581 /** Export \ref vigra::Neighborhood3DTwentySix::NeighborCode3D into the scope of namespace vigra.
01582  */
01583 typedef Neighborhood3DTwentySix::NeighborCode3D NeighborCode3DTwentySix;
01584 
01585 //@}
01586 
01587 } // namespace vigra
01588 
01589 #endif /* VIGRA_VOXELNEIGHBORHOOD_HXX */

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de)
Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany

html generated using doxygen and Python
VIGRA 1.6.0 (5 Nov 2009)