GCC Code Coverage Report


Directory: ./
File: src/2geom/sweep-bounds.cpp
Date: 2024-03-18 17:01:34
Exec Total Coverage
Lines: 0 67 0.0%
Functions: 0 5 0.0%
Branches: 0 110 0.0%

Line Branch Exec Source
1 #include <2geom/sweep-bounds.h>
2
3 #include <algorithm>
4
5 namespace Geom {
6
7 struct Event {
8 double x;
9 unsigned ix;
10 bool closing;
11 Event(double pos, unsigned i, bool c) : x(pos), ix(i), closing(c) {}
12 // Lexicographic ordering by x then closing
13 bool operator<(Event const &other) const {
14 if(x < other.x) return true;
15 if(x > other.x) return false;
16 return closing < other.closing;
17 }
18 bool operator==(Event const &other) const {
19 return other.x == x && other.ix == ix && other.closing == closing;
20 }
21 };
22
23 std::vector<std::vector<unsigned> > fake_cull(unsigned a, unsigned b);
24
25 /**
26 * \brief Make a list of pairs of self intersections in a list of Rects.
27 *
28 * \param rs: vector of Rect.
29 * \param d: dimension to sweep along
30 *
31 * [(A = rs[i], B = rs[j]) for i,J in enumerate(pairs) for j in J]
32 * then A.left <= B.left
33 */
34
35 std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> rs, Dim2 d) {
36 std::vector<Event> events; events.reserve(rs.size()*2);
37 std::vector<std::vector<unsigned> > pairs(rs.size());
38
39 for(unsigned i = 0; i < rs.size(); i++) {
40 events.emplace_back(rs[i][d].min(), i, false);
41 events.emplace_back(rs[i][d].max(), i, true);
42 }
43 std::sort(events.begin(), events.end());
44
45 std::vector<unsigned> open;
46 for(auto & event : events) {
47 unsigned ix = event.ix;
48 if(event.closing) {
49 std::vector<unsigned>::iterator iter = std::find(open.begin(), open.end(), ix);
50 //if(iter != open.end())
51 open.erase(iter);
52 } else {
53 for(unsigned int jx : open) {
54 if(rs[jx][1-d].intersects(rs[ix][1-d])) {
55 pairs[jx].push_back(ix);
56 }
57 }
58 open.push_back(ix);
59 }
60 }
61 return pairs;
62 }
63
64 /**
65 * \brief Make a list of pairs of red-blue intersections between two lists of Rects.
66 *
67 * \param a: vector of Rect.
68 * \param b: vector of Rect.
69 * \param d: dimension to scan along
70 *
71 * [(A = rs[i], B = rs[j]) for i,J in enumerate(pairs) for j in J]
72 * then A.left <= B.left, A in a, B in b
73 */
74 std::vector<std::vector<unsigned> > sweep_bounds(std::vector<Rect> a, std::vector<Rect> b, Dim2 d) {
75 std::vector<std::vector<unsigned> > pairs(a.size());
76 if(a.empty() || b.empty()) return pairs;
77 std::vector<Event> events[2];
78 events[0].reserve(a.size()*2);
79 events[1].reserve(b.size()*2);
80
81 for(unsigned n = 0; n < 2; n++) {
82 unsigned sz = n ? b.size() : a.size();
83 events[n].reserve(sz*2);
84 for(unsigned i = 0; i < sz; i++) {
85 Rect r = n ? b[i] : a[i];
86 events[n].emplace_back(r[d].min(), i, false);
87 events[n].emplace_back(r[d].max(), i, true);
88 }
89 std::sort(events[n].begin(), events[n].end());
90 }
91
92 std::vector<unsigned> open[2];
93 bool n = events[1].front() < events[0].front();
94 {// As elegant as putting the initialiser in the for was, it upsets some legacy compilers (MS VS C++)
95 unsigned i[] = {0,0};
96 for(; i[n] < events[n].size();) {
97 unsigned ix = events[n][i[n]].ix;
98 bool closing = events[n][i[n]].closing;
99 //std::cout << n << "[" << ix << "] - " << (closing ? "closer" : "opener") << "\n";
100 if(closing) {
101 open[n].erase(std::find(open[n].begin(), open[n].end(), ix));
102 } else {
103 if(n) {
104 //n = 1
105 //opening a B, add to all open a
106 for(unsigned int jx : open[0]) {
107 if(a[jx][1-d].intersects(b[ix][1-d])) {
108 pairs[jx].push_back(ix);
109 }
110 }
111 } else {
112 //n = 0
113 //opening an A, add all open b
114 for(unsigned int jx : open[1]) {
115 if(b[jx][1-d].intersects(a[ix][1-d])) {
116 pairs[ix].push_back(jx);
117 }
118 }
119 }
120 open[n].push_back(ix);
121 }
122 i[n]++;
123 if(i[n]>=events[n].size()) {break;}
124 n = (events[!n][i[!n]] < events[n][i[n]]) ? !n : n;
125 }}
126 return pairs;
127 }
128
129 //Fake cull, until the switch to the real sweep is made.
130 std::vector<std::vector<unsigned> > fake_cull(unsigned a, unsigned b) {
131 std::vector<std::vector<unsigned> > ret;
132
133 std::vector<unsigned> all;
134 for(unsigned j = 0; j < b; j++)
135 all.push_back(j);
136
137 for(unsigned i = 0; i < a; i++)
138 ret.push_back(all);
139
140 return ret;
141 }
142
143 }
144
145 /*
146 Local Variables:
147 mode:c++
148 c-file-style:"stroustrup"
149 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
150 indent-tabs-mode:nil
151 fill-column:99
152 End:
153 */
154 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
155