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 . Use the Table of Contents for navigation.