physical.hpp

Go to the documentation of this file.
00001 
00028 #ifndef MSMAZES_CORE_PATTERN_PHYSICAL_HPP
00029 #define MSMAZES_CORE_PATTERN_PHYSICAL_HPP
00030 
00031 #include <boost/mpl/bool.hpp>  // boost::mpl::false_
00032 #include <boost/numeric/ublas/vector.hpp>  // boost::numeric::ublas::vector
00033 #include <boost/graph/adjacency_list.hpp>  // boost::container_gen
00034 #include <msmazes/core/pattern/keywords.hpp>  // Boost.Parameter keyword objects
00035 #include <msmazes/core/pattern/base.hpp>  // msmazes::BasePattern
00036 
00384 namespace msmazes {
00385   namespace _detail {
00386 
00391     struct PhysicalCellEqualityPolicy
00392     {
00393         template <typename Cell>
00394         bool operator()(const Cell& c1, const Cell& c2) const
00395         {
00396             return (c1[0] == c2[0]) && (c1[1] == c2[1]) && (c1[2] == c2[2]);
00397         }
00398     };
00399   }  // namespace _detail
00400 
00402 
00461 template <
00462     typename TesselationSelector
00463 >
00464 struct TesselationFormerGenerator
00465 {
00466 };
00467 
00469 
00548 template <
00549 #ifndef MSMAZES_DOX
00550     typename CoordinateType
00551   , typename DirectionType
00552   , typename DirectionChangeType
00553   , typename CellContainerSelector
00554 #endif  /* MSMAZES_DOX */
00555 >
00556 class PhysicalPattern
00557 #ifndef MSMAZES_DOX
00558   : public BasePattern<
00559                boost::undirectedS
00560              , boost::numeric::ublas::vector<CoordinateType>
00561              , _detail::PhysicalCellEqualityPolicy
00562              , DirectionType
00563              , typename boost::container_gen<
00564                    CellContainerSelector
00565                  , boost::numeric::ublas::vector<CoordinateType>
00566                >::type
00567            >
00568 #endif  /* MSMAZES_DOX */
00569 {
00570 #ifndef MSMAZES_DOX
00571  private:
00572     typedef BasePattern<
00573                 boost::undirectedS
00574               , boost::numeric::ublas::vector<CoordinateType>
00575               , _detail::PhysicalCellEqualityPolicy
00576               , DirectionType
00577               , typename boost::container_gen<
00578                     CellContainerSelector
00579                   , boost::numeric::ublas::vector<CoordinateType>
00580                 >::type
00581             >
00582             ParentPattern;
00583 #endif  /* MSMAZES_DOX */
00584 
00585  public:
00590 #ifdef MSMAZES_DOX
00591     typedef implementation_defined Cell;
00592 #else
00593     typedef typename ParentPattern::Cell
00594             Cell;
00595 #endif  /* MSMAZES_DOX */
00596 
00602 #ifdef MSMAZES_DOX
00603     typedef implementation_defined Coordinate;
00604 #else
00605     typedef CoordinateType
00606             Coordinate;
00607 #endif  /* MSMAZES_DOX */
00608 
00614 #ifdef MSMAZES_DOX
00615     typedef implementation_defined CellEqualityPolicy;
00616 #else
00617     typedef typename ParentPattern::CellEqualityPolicy
00618             CellEqualityPolicy;
00619 #endif  /* MSMAZES_DOX */
00620 
00626 #ifdef MSMAZES_DOX
00627     typedef implementation_defined Graph;
00628 #else
00629     typedef typename ParentPattern::Graph
00630             Graph;
00631 #endif  /* MSMAZES_DOX */
00632 
00638 #ifdef MSMAZES_DOX
00639     typedef implementation_defined CellIndex;
00640 #else
00641     typedef typename ParentPattern::CellIndex
00642             CellIndex;
00643 #endif  /* MSMAZES_DOX */
00644 
00650 #ifdef MSMAZES_DOX
00651     typedef implementation_defined EdgeDirectedCategory;
00652 #else
00653     typedef typename ParentPattern::EdgeDirectedCategory
00654             EdgeDirectedCategory;
00655 #endif  /* MSMAZES_DOX */
00656 
00662 #ifdef MSMAZES_DOX
00663     typedef implementation_defined Direction;
00664 #else
00665     typedef typename ParentPattern::Direction
00666             Direction;
00667 #endif  /* MSMAZES_DOX */
00668 
00675 #ifdef MSMAZES_DOX
00676     typedef implementation_defined DirectionChange;
00677 #else
00678     typedef DirectionChangeType
00679             DirectionChange;
00680 #endif  /* MSMAZES_DOX */
00681 
00687 #ifdef MSMAZES_DOX
00688     typedef implementation_defined OutDegree;
00689 #else
00690     typedef typename boost::graph_traits<Graph>::degree_size_type
00691             OutDegree;
00692 #endif  /* MSMAZES_DOX */
00693 
00699 #ifdef MSMAZES_DOX
00700     typedef implementation_defined HasIndexableEndpointCells;
00701 #else
00702     typedef boost::mpl::false_
00703             HasIndexableEndpointCells;
00704 #endif  /* MSMAZES_DOX */
00705 
00706  private:
00707     Cell _entrance_cell;
00708     Cell _exit_cell;
00709     Cell _source_cell;
00710     Cell _target_cell;
00711 
00712     PhysicalPattern(const PhysicalPattern& copy)
00713     {
00714     }
00715 
00716  protected:
00718 
00724     PhysicalPattern()
00725       : ParentPattern()
00726       , _entrance_cell(3)
00727       , _exit_cell(3)
00728       , _source_cell(3)
00729       , _target_cell(3)
00730     {
00731     }
00732 
00733  public:
00735 
00738     virtual ~PhysicalPattern()
00739     {
00740     }
00741 
00771     static Cell
00772         createCell(
00773             const Coordinate x
00774           , const Coordinate y
00775           , const Coordinate z
00776         )
00777     {
00778         Cell cell(3);
00779 
00780         cell[0] = x;
00781         cell[1] = y;
00782         cell[2] = z;
00783 
00784         return cell;
00785     }
00786 
00787  protected:
00817     template <
00818         typename TesselationFormer
00819       , typename ArgumentPack
00820     >
00821     void
00822         initializeWithTesselationFormer(
00823             const TesselationFormer& tesselation_former
00824           , const ArgumentPack& p
00825         )
00826     {
00827         ParentPattern::initializeWithPatternFormer(tesselation_former, p);
00828         _entrance_cell = p[init_entrance_cell_arg];
00829         _exit_cell     = p[init_exit_cell_arg];
00830 
00831         const Cell& zero_cell = getCell(0);
00832 
00833         _source_cell[0] = zero_cell[0];
00834         _source_cell[1] = zero_cell[1];
00835         _source_cell[2] = zero_cell[2];
00836 
00837         Coordinate
00838             diff_x = _source_cell[0] - _entrance_cell[0];
00839         Coordinate
00840             diff_y = _source_cell[1] - _entrance_cell[1];
00841         Coordinate
00842             diff_z = _source_cell[2] - _entrance_cell[2];
00843         Coordinate
00844             min_prod = diff_x * diff_x + diff_y * diff_y + diff_z * diff_z;
00845         Coordinate
00846             dot_prod;
00847         CellIndex
00848             i = getCellCount();
00849 
00850         while (--i > 0)
00851         {
00852             const Cell& cell = getCell(i);
00853 
00854             diff_x   = cell[0] - _entrance_cell[0];
00855             diff_y   = cell[1] - _entrance_cell[1];
00856             diff_z   = cell[2] - _entrance_cell[2];
00857             dot_prod = diff_x * diff_x + diff_y * diff_y + diff_z * diff_z;
00858 
00859             if (dot_prod < min_prod)
00860             {
00861                 min_prod        = dot_prod;
00862                 _source_cell[0] = cell[0];
00863                 _source_cell[1] = cell[1];
00864                 _source_cell[2] = cell[2];
00865             }
00866         }
00867 
00868         _target_cell[0] = zero_cell[0];
00869         _target_cell[1] = zero_cell[1];
00870         _target_cell[2] = zero_cell[2];
00871         diff_x          = _target_cell[0] - _exit_cell[0];
00872         diff_y          = _target_cell[1] - _exit_cell[1];
00873         diff_z          = _target_cell[2] - _exit_cell[2];
00874         min_prod        = diff_x * diff_x + diff_y * diff_y + diff_z * diff_z;
00875         i               = getCellCount();
00876 
00877         while (--i > 0)
00878         {
00879             const Cell& cell = getCell(i);
00880 
00881             diff_x   = cell[0] - _exit_cell[0];
00882             diff_y   = cell[1] - _exit_cell[1];
00883             diff_z   = cell[2] - _exit_cell[2];
00884             dot_prod = diff_x * diff_x + diff_y * diff_y + diff_z * diff_z;
00885 
00886             if (dot_prod < min_prod)
00887             {
00888                 min_prod        = dot_prod;
00889                 _target_cell[0] = cell[0];
00890                 _target_cell[1] = cell[1];
00891                 _target_cell[2] = cell[2];
00892             }
00893         }
00894     }
00895 
00896  public:
00903     inline const Graph& getGraph() const
00904     {
00905         return ParentPattern::getGraph();
00906     }
00907 
00913     inline CellIndex getCellCount() const
00914     {
00915         return ParentPattern::getCellCount();
00916     }
00917 
00924     inline const Cell& getCell(const CellIndex index) const
00925     {
00926         return ParentPattern::getCell(index);
00927     }
00928 
00934     inline const Cell& getEntranceCell() const
00935     {
00936         return _entrance_cell;
00937     }
00938 
00945     inline const Cell& getSourceCell() const
00946     {
00947         return _source_cell;
00948     }
00949 
00956     inline const Cell& getTargetCell() const
00957     {
00958         return _target_cell;
00959     }
00960 
00966     inline const Cell& getExitCell() const
00967     {
00968         return _exit_cell;
00969     }
00970 
00971  protected:
00977     virtual Direction
00978         getEdgeDirectionDerived(
00979             const Cell& source
00980           , const Cell& target
00981         ) const
00982     {
00983         return ParentPattern::getEdgeDirectionDerived(source, target);
00984     }
00985 
00991     virtual DirectionChange
00992         getYawTurnDerived(
00993             const Cell& source
00994           , const Cell& parent
00995           , const Cell& target
00996         ) const
00997     {
00998         return DirectionChange();
00999     }
01000 
01006     virtual OutDegree getMaxOutDegreeDerived() const = 0;
01007 
01008  public:
01015     Direction
01016         getEdgeDirection(
01017             const CellIndex source_index
01018           , const CellIndex target_index
01019         ) const
01020     {
01021         return ParentPattern::getEdgeDirection(source_index, target_index);
01022     }
01023 
01030     DirectionChange
01031         getYawTurn(
01032             const CellIndex source_index
01033           , const CellIndex parent_index
01034           , const CellIndex target_index
01035         ) const
01036     {
01037         const Cell&
01038             source
01039               = (source_index == parent_index)
01040               ? getEntranceCell()
01041               : getCell(source_index);
01042         const Cell&
01043             parent
01044               = getCell(parent_index);
01045         const Cell&
01046             target
01047               = (target_index == getCellCount())
01048               ? getExitCell()
01049               : getCell(target_index);
01050 
01051         return getYawTurnDerived(source, parent, target);
01052     }
01053 
01059     OutDegree getMaxOutDegree() const
01060     {
01061         return getMaxOutDegreeDerived();
01062     }
01063 };
01064 }  // namespace msmazes
01065 
01066 #endif  /* MSMAZES_CORE_PATTERN_PHYSICAL_HPP */

Multi-State Mazes in C++ is hosted by SourceForge.net. Use the Table of Contents for navigation.