12#include <unordered_set>
27 class Subpaving :
public std::list<IntervalVector>
31 Subpaving(std::initializer_list<IntervalVector> l)
32 : std::list<IntervalVector>(l)
34 assert_release(!this->empty());
37 Subpaving(
const std::list<IntervalVector>& l)
38 : std::list<IntervalVector>(l)
40 assert_release(!this->empty());
43 IntervalVector box()
const
45 IntervalVector h = IntervalVector::empty(this->front().size());
46 for(
const auto& bi : *
this)
51 std::list<IntervalVector> boxes()
const
57 std::list<IntervalVector> contour(
bool sort =
false)
const
59 if constexpr(std::is_same_v<PavingOut,P>)
60 return contour(PavingOut::outer_complem, sort);
62 else if constexpr(std::is_same_v<PavingInOut,P>)
63 return contour(PavingInOut::outer_complem, sort);
67 assert_release(
false &&
68 "cannot find a default complementary \"node value\" function for such Subaving class");
73 std::list<IntervalVector> contour(
const P::NodeValue_& node_complementary_value =
nullptr,
bool sort =
false)
const
75 std::list<IntervalVector> l_bound;
77 for(
const auto& xi : *
this)
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;
83 for(
const auto& neighb_ni : neighb_nodes)
84 neighb_boxes.splice(neighb_boxes.end(), node_complementary_value(neighb_ni));
86 for(
const auto& x_bi : x_boxes)
87 for(
const auto& neighb_bi : neighb_boxes)
89 auto inter = x_bi & neighb_bi;
90 if(!inter.is_empty() && !inter.is_degenerated())
91 l_bound.push_back(inter);
96 remove_duplicates_from_list(l_bound);
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;
103 static Vector next_pt(
const IntervalVector& x,
const Vector& pt)
105 assert(!x.is_degenerated());
106 assert(x.size() == 2 && pt.size() == 2);
108 assert(x.lb() == pt || x.ub() == pt);
109 return pt == x.lb() ? x.ub() : x.lb();
112 std::list<IntervalVector> sort_contour(std::list<IntervalVector> l)
const
114 assert_release(!l.empty());
115 assert_release(l.front().size() == 2 &&
"only 2d contours can be sorted");
117 const Index nl = l.size();
119 Vector current_pt = l.front().ub(), first_pt = current_pt;
120 std::list<IntervalVector> s { l.front() };
125 std::list<IntervalVector>::iterator it = l.begin();
128 if(it->contains(current_pt))
131 current_pt = Subpaving<P>::next_pt(*it, current_pt);
140 if(current_pt == first_pt)
144 assert(nl == s.size());
150 using SubpavingOut = Subpaving<PavingOut>;
151 using SubpavingInOut = Subpaving<PavingInOut>;