codac 1.5.6
Loading...
Searching...
No Matches
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"
20
21namespace 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