codac  1.5.7
codac2_Paving.h
Go to the documentation of this file.
1 
12 #ifndef __CODAC2_PAVING_H__
13 #define __CODAC2_PAVING_H__
14 
15 #include <list>
16 #include <memory>
17 #include <functional>
18 #include "codac2_Interval.h"
19 #include "codac2_IntervalVector.h"
20 
21 namespace codac2
22 {
23  template<class P,int N=Dynamic>
24  class PavingBase
25  {
26  public:
27 
28  explicit PavingBase(const IntervalVector_<N>& x)
29  : _x(x)
30  {
31 
32  }
33 
34  virtual ~PavingBase() = default;
35 
36  const IntervalVector_<N>& box() const
37  {
38  return _x;
39  }
40 
41  std::shared_ptr<P> left()
42  {
43  return _left;
44  }
45 
46  std::shared_ptr<P> right()
47  {
48  return _right;
49  }
50 
51  bool is_empty() const
52  {
53  if(is_leaf())
54  return _x.is_empty();
55 
56  else
57  return (_left && _left->is_empty()) && (_right && _right->is_empty());
58  }
59 
60  bool is_leaf() const
61  {
62  return not _left && not _right;
63  }
64 
65  double volume() const
66  {
67  if(is_leaf())
68  return _x.volume();
69  double v = 0.;
70  if(_left) v += _left->volume();
71  if(_right) v += _right->volume();
72  return v;
73  }
74 
75  virtual void bisect(float ratio = 0.49)
76  {
77  assert(Interval(0.,1.).interior_contains(ratio));
78  assert(is_leaf() && "only leaves can be bisected");
79  assert(_x.is_bisectable());
80  auto p = _x.bisect(ratio);
81  _left = std::make_shared<P>(p.first);
82  _right = std::make_shared<P>(p.second);
83  }
84 
85  IntervalVector_<N> hull_box() const
86  {
87  if(is_leaf())
88  return _x;
89  auto hull = IntervalVector_<N>::empty_set();
90  if(_left) hull |= _left->hull_box();
91  if(_right) hull |= _right->hull_box();
92  return hull;
93  }
94 
95  std::list<std::reference_wrapper<const IntervalVector_<N>>> boxes_list(const IntervalVector_<N>& intersect = IntervalVector_<N>()) const
96  {
97  std::list<std::reference_wrapper<const IntervalVector_<N>>> l;
98  boxes_list_push(l, intersect);
99  return l;
100  }
101 
102  std::list<P*> leaves_list()
103  {
104  std::list<P*> l;
105  leaves_list_push(l);
106  return l;
107  }
108 
109  protected:
110 
111  void boxes_list_push(std::list<std::reference_wrapper<const IntervalVector_<N>>>& l, const IntervalVector_<N>& intersect = IntervalVector_<N>()) const
112  {
113  if(is_leaf() && !_x.is_empty() && _x.intersects(intersect))
114  l.push_back(std::cref(_x));
115  else
116  {
117  if(_left) _left->boxes_list_push(l);
118  if(_right) _right->boxes_list_push(l);
119  }
120  }
121 
122  void leaves_list_push(std::list<P*>& l)
123  {
124  if(is_leaf() && !_x.is_empty())
125  l.push_back(dynamic_cast<P*>(this));
126  else
127  {
128  if(_left) _left->leaves_list_push(l);
129  if(_right) _right->leaves_list_push(l);
130  }
131  }
132 
133  public: // todo
134 
135  IntervalVector_<N> _x;
136  std::shared_ptr<P> _left = nullptr, _right = nullptr;
137  };
138 
139  template<int N>
140  class Paving : public PavingBase<Paving<N>,N>
141  {
142  public:
143 
144  explicit Paving(size_t n)
145  : PavingBase<Paving<N>,N>(IntervalVector_<N>(n))
146  { }
147 
148  explicit Paving(const IntervalVector_<N>& x)
149  : PavingBase<Paving<N>,N>(x)
150  { }
151  };
152 
153 
154 } // namespace codac
155 
156 #endif