codac 2.0.0
Loading...
Searching...
No Matches
codac2_Subpaving.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#include <unordered_set>
13#include <list>
14#include <memory>
15#include "codac2_assert.h"
17#include "codac2_Paving.h"
19#include "codac2_Figure2D.h"
20
21namespace codac2
22{
23 template<typename P>
24 class PavingNode;
25
26 template<typename P>
27 class Subpaving : public std::list<IntervalVector>
28 {
29 public:
30
31 Subpaving(std::initializer_list<IntervalVector> l)
32 : std::list<IntervalVector>(l)
33 {
34 assert_release(!this->empty());
35 }
36
37 Subpaving(const std::list<IntervalVector>& l)
38 : std::list<IntervalVector>(l)
39 {
40 assert_release(!this->empty());
41 }
42
43 IntervalVector box() const
44 {
45 IntervalVector h = IntervalVector::empty(this->front().size());
46 for(const auto& bi : *this)
47 h |= bi;
48 return h;
49 }
50
51 std::list<IntervalVector> boxes() const
52 {
53 return *this;
54 }
55
56 #if 0
57 std::list<IntervalVector> contour(bool sort = false) const
58 {
59 if constexpr(std::is_same_v<PavingOut,P>)
60 return contour(PavingOut::outer_complem, sort);
61
62 else if constexpr(std::is_same_v<PavingInOut,P>)
63 return contour(PavingInOut::outer_complem, sort);
64
65 else
66 {
67 assert_release(false &&
68 "cannot find a default complementary \"node value\" function for such Subaving class");
69 return { };
70 }
71 }
72
73 std::list<IntervalVector> contour(const P::NodeValue_& node_complementary_value = nullptr, bool sort = false) const
74 {
75 std::list<IntervalVector> l_bound;
76
77 for(const auto& xi : *this)
78 {
79 auto x_boxes = _node_value(xi);
80 auto neighb_nodes = this->front()->paving().neighbours(xi, _node_value, node_complementary_value);
81 std::list<IntervalVector> neighb_boxes;
82
83 for(const auto& neighb_ni : neighb_nodes)
84 neighb_boxes.splice(neighb_boxes.end(), node_complementary_value(neighb_ni));
85
86 for(const auto& x_bi : x_boxes)
87 for(const auto& neighb_bi : neighb_boxes)
88 {
89 auto inter = x_bi & neighb_bi;
90 if(!inter.is_empty() && !inter.is_degenerated())
91 l_bound.push_back(inter);
92 }
93 }
94
95 // Removing duplicates
96 remove_duplicates_from_list(l_bound);
97
98 assert([&]() -> bool { for(const auto& bi : l_bound) { if(!bi.is_flat()) return false; } return true; } ()
99 && "boundary boxes should be flat");
100 return sort ? sort_contour(l_bound) : l_bound;
101 }
102
103 static Vector next_pt(const IntervalVector& x, const Vector& pt)
104 {
105 assert(!x.is_degenerated());
106 assert(x.size() == 2 && pt.size() == 2);
107 assert(x.is_flat());
108 assert(x.lb() == pt || x.ub() == pt);
109 return pt == x.lb() ? x.ub() : x.lb();
110 }
111
112 std::list<IntervalVector> sort_contour(std::list<IntervalVector> l) const
113 {
114 assert_release(!l.empty());
115 assert_release(l.front().size() == 2 && "only 2d contours can be sorted");
116
117 const Index nl = l.size();
118
119 Vector current_pt = l.front().ub(), first_pt = current_pt;
120 std::list<IntervalVector> s { l.front() };
121 l.pop_front();
122
123 while(!l.empty())
124 {
125 std::list<IntervalVector>::iterator it = l.begin();
126 while(it != l.end())
127 {
128 if(it->contains(current_pt))
129 {
130 s.push_back(*it);
131 current_pt = Subpaving<P>::next_pt(*it, current_pt);
132 l.erase(it);
133 break;
134 }
135
136 else
137 ++it;
138 }
139
140 if(current_pt == first_pt)
141 break;
142 }
143
144 assert(nl == s.size());
145 return s;
146 }
147 #endif
148 };
149
150 using SubpavingOut = Subpaving<PavingOut>;
151 using SubpavingInOut = Subpaving<PavingInOut>;
152}