basin.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #ifndef BASIN_HPP
  2. #define BASIN_HPP
  3. #include <string>
  4. using namespace std;
  5. enum Direction{Left,Right,Both};
  6. enum BasinPosition{Middle,BorderLeft,BorderRight};
  7. struct Summit{
  8. size_t ix;
  9. double h;
  10. bool operator<(const Summit& S) const;
  11. Summit(size_t ix,double h);
  12. };
  13. class Basin{
  14. public:
  15. static constexpr double delta_both_leak=0.01;
  16. size_t xleft,xright;
  17. size_t xbottom; //Used only for primitives bassin
  18. Direction leak_direction;
  19. BasinPosition position;
  20. //Basin* neighbours[2];
  21. double hmin,hleft,hright;
  22. Basin* left;
  23. Basin* right;
  24. void compute_leak_direction();
  25. public:
  26. Basin();
  27. Basin(Basin* left,Basin* right);
  28. void display(string indent="");
  29. bool is_primitive();
  30. };
  31. inline
  32. Summit::Summit(size_t ix_,double h_):ix(ix_),h(h_){
  33. }
  34. inline bool
  35. Summit::operator<(const Summit& S) const{
  36. return h<S.h;
  37. }
  38. inline Basin::Basin(){
  39. left=nullptr;
  40. right=nullptr;
  41. position=Middle;
  42. }
  43. inline void
  44. Basin::compute_leak_direction(){
  45. switch(position){
  46. case Middle:
  47. if(abs(hleft-hright)<delta_both_leak) leak_direction=Both;
  48. else leak_direction=(hleft>hright)?Right:Left;
  49. break;
  50. case BorderLeft:
  51. leak_direction=Right;
  52. break;
  53. case BorderRight:
  54. leak_direction=Left;
  55. break;
  56. default:
  57. break;
  58. };
  59. }
  60. inline Basin::Basin(Basin* left_,Basin* right_){
  61. left=left_;
  62. right=right_;
  63. xleft=left->xleft;
  64. xright=right->xright;
  65. hleft=left->hleft;
  66. hright=right->hright;
  67. hmin=min(left->hmin,right->hmin);
  68. if(left->position==BorderLeft) position=BorderLeft;
  69. else if(right->position==BorderRight) position=BorderRight;
  70. else position=Middle;
  71. compute_leak_direction();
  72. }
  73. inline void Basin::display(string indent){
  74. cout<<indent<<'['<<xleft<<','<<xright<<']'<<endl;
  75. if(left==nullptr) return;
  76. left->display(indent+' ');
  77. right->display(indent+' ');
  78. }
  79. inline
  80. bool Basin::is_primitive(){
  81. return left=nullptr;
  82. }
  83. #endif